#include "tool_cb_rea.h"
#include "tool_operate.h"
#include "tool_util.h"
+#include "tool_msgs.h"
#include "memdebug.h" /* keep this as LAST include */
size_t tool_read_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
{
ssize_t rc = 0;
- struct InStruct *in = userdata;
- struct OperationConfig *config = in->config;
+ struct per_transfer *per = userdata;
+ struct OperationConfig *config = per->config;
+
+ if((per->uploadfilesize != -1) &&
+ (per->uploadedsofar == per->uploadfilesize)) {
+ /* done */
+ return 0;
+ }
if(config->timeout_ms) {
struct timeval now = tvnow();
- long msdelta = tvdiff(now, in->per->start);
+ long msdelta = tvdiff(now, per->start);
if(msdelta > config->timeout_ms)
/* timeout */
timeout.tv_usec = (int)((wait%1000)*1000);
FD_ZERO(&bits);
- FD_SET(in->fd, &bits);
- if(!select(in->fd + 1, &bits, NULL, NULL, &timeout))
+ FD_SET(per->infd, &bits);
+ if(!select(per->infd + 1, &bits, NULL, NULL, &timeout))
return 0; /* timeout */
}
#endif
}
- rc = read(in->fd, buffer, sz*nmemb);
+ rc = read(per->infd, buffer, sz*nmemb);
if(rc < 0) {
if(errno == EAGAIN) {
errno = 0;
- in->config->readbusy = TRUE;
+ config->readbusy = TRUE;
return CURL_READFUNC_PAUSE;
}
/* since size_t is unsigned we can't return negative values fine */
rc = 0;
}
- in->config->readbusy = FALSE;
+ if((per->uploadfilesize != -1) &&
+ (per->uploadedsofar + rc > per->uploadfilesize)) {
+ /* do not allow uploading more than originally set out to do */
+ curl_off_t delta = per->uploadedsofar + rc - per->uploadfilesize;
+ warnf(per->config->global, "File size larger in the end than when "
+ "started. Dropping at least %" CURL_FORMAT_CURL_OFF_T " bytes",
+ delta);
+ rc = (ssize_t)(per->uploadfilesize - per->uploadedsofar);
+ }
+ config->readbusy = FALSE;
/* when select() returned zero here, it timed out */
return (size_t)rc;
#include "curlx.h"
#include "tool_cfgable.h"
+#include "tool_operate.h"
#include "tool_cb_see.h"
#include "memdebug.h" /* keep this as LAST include */
int tool_seek_cb(void *userdata, curl_off_t offset, int whence)
{
- struct InStruct *in = userdata;
+ struct per_transfer *per = userdata;
#if(SIZEOF_CURL_OFF_T > SIZEOF_OFF_T) && !defined(USE_WIN32_LARGE_FILES)
}
#endif
- if(LSEEK_ERROR == lseek(in->fd, offset, whence))
+ if(LSEEK_ERROR == lseek(per->infd, offset, whence))
/* couldn't rewind, the reason is in errno but errno is just not portable
enough and we don't actually care that much why we failed. We'll let
libcurl know that it may try other means if it wants to. */
#include "tool_setup.h"
#include "tool_cfgable.h"
+#include "tool_formparse.h"
#include "tool_main.h"
#include "memdebug.h" /* keep this as LAST include */
#include "tool_setup.h"
#include "tool_sdecls.h"
#include "tool_urlglob.h"
-#include "tool_formparse.h"
struct GlobalConfig;
#endif
my_setopt(per->curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
}
- per->input.fd = per->infd;
}
+ per->uploadfilesize = uploadfilesize;
per->start = tvnow();
return result;
}
if(state->up < state->infilenum) {
struct per_transfer *per = NULL;
struct OutStruct *outs;
- struct InStruct *input;
struct OutStruct *heads;
struct OutStruct *etag_save;
struct HdrCbData *hdrcbdata = NULL;
hdrcbdata = &per->hdrcbdata;
outs = &per->outs;
- input = &per->input;
per->outfile = NULL;
per->infdopen = FALSE;
/* what call to write */
my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb);
- /* for uploads */
- input->config = config;
- input->per = per;
/* Note that if CURLOPT_READFUNCTION is fread (the default), then
* lib/telnet.c will Curl_poll() on the input file descriptor
* rather than calling the READFUNCTION at regular intervals.
* behavior, by omitting to set the READFUNCTION & READDATA options,
* have not been determined.
*/
- my_setopt(curl, CURLOPT_READDATA, input);
+ my_setopt(curl, CURLOPT_READDATA, per);
/* what call to read */
my_setopt(curl, CURLOPT_READFUNCTION, tool_read_cb);
/* in 7.18.0, the CURLOPT_SEEKFUNCTION/DATA pair is taking over what
CURLOPT_IOCTLFUNCTION/DATA pair previously provided for seeking */
- my_setopt(curl, CURLOPT_SEEKDATA, input);
+ my_setopt(curl, CURLOPT_SEEKDATA, per);
my_setopt(curl, CURLOPT_SEEKFUNCTION, tool_seek_cb);
{
struct OutStruct outs;
struct OutStruct heads;
struct OutStruct etag_save;
- struct InStruct input;
struct HdrCbData hdrcbdata;
long num_headers;
bool was_last_header_empty;
curl_off_t dlnow;
curl_off_t ultotal;
curl_off_t ulnow;
+ curl_off_t uploadfilesize; /* expected total amount */
+ curl_off_t uploadedsofar; /* amount delivered from the callback */
bool dltotal_added; /* if the total has been added from this */
bool ultotal_added;
curl_off_t init;
};
-
-/*
- * InStruct variables keep track of information relative to curl's
- * input reading, which may take place from stdin or from some file.
- *
- * 'fd' member is either 'stdin' file descriptor number STDIN_FILENO
- * or a file descriptor as returned from an 'open' call for some file.
- *
- * 'config' member is a pointer to associated 'OperationConfig' struct.
- */
-
-struct InStruct {
- int fd;
- struct OperationConfig *config;
- struct per_transfer *per;
-};
-
-
/*
* A linked list of these 'getout' nodes contain URL's to fetch,
* as well as information relative to where URL contents should