[PATCH] wget: add timeout parameter

Matthias Kaehlcke matthias at kaehlcke.net
Tue Nov 18 12:56:19 UTC 2008


El Tue, Aug 19, 2008 at 04:26:26PM +0200 Bernhard Reutner-Fischer ha dit:

> On Tue, Aug 19, 2008 at 03:58:12PM +0200, Matthias Kaehlcke wrote:
> >Hi Bernhard,
> >
> >El Tue, Aug 19, 2008 at 01:57:13PM +0200 Bernhard Reutner-Fischer ha dit:
> >
> >> ...
> >>
> >> Care to resend?
> >
> >thanks for your review and your constructive comments. here is a new
> >version of the patch that adresses the issues you brought up.
> >
> >> PS: a size(1) would have been nice
> >
> >what does size(1) mean? a patch with zero impact on the size of the
> >binary? if desired i can add a config option for the timeout
> >parameter
> 
> I ment the size output from before and after your patch. Ideally every
> patch would reduce the total size, regardless whether the patch adds or
> removes a feature, but that's of course not (always) possible. I don't
> think a config option for the timeout makes sense.
> 
> Thanks for the updated patch, i'll test and apply it soon (unless
> somebody beats me to it).
> If you experience size-increase with using "quiet" instead of looking at
> opt (i didn't try), then please follow-up.

here is a new version of the patch against busybox 1.13.0

below the stats you asked me for

size busybox.org
   text    data     bss     dec     hex filename
 678767    2168    9396  690331   a889b busybox

size busybox
   text    data     bss     dec     hex filename
 678651    2168    9396  690215   a8827 busybox


bloat-o-meter output:

function                                             old     new
delta
.rodata                                           123186  123201
+15
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 15/0)               Total:
15 bytes

---

--- busybox-1.13.0.org/networking/wget.c	2008-11-18 11:58:24.000000000 +0100
+++ busybox-1.13.0/networking/wget.c	2008-11-18 12:13:12.000000000 +0100
@@ -29,9 +29,10 @@
 	off_t transferred;        /* Number of bytes transferred so far */
 	const char *curfile;      /* Name of current file being transferred */
 	unsigned lastupdate_sec;
-	unsigned start_sec;
 #endif
-	smallint chunked;             /* chunked transfer encoding */
+	unsigned start_sec;
+	smallint flags;
+	unsigned timeout;         /* Operation timeout */
 };
 #define G (*(struct globals*)&bb_common_bufsiz1)
 struct BUG_G_too_big {
@@ -45,9 +46,16 @@
 #define curfile         (G.curfile        )
 #define lastupdate_sec  (G.lastupdate_sec )
 #define start_sec       (G.start_sec      )
-#define chunked         (G.chunked        )
+#define flags           (G.flags          )
+#define timeout         (G.timeout        )
 #define INIT_G() do { } while (0)
 
+#define WGET_CHUNKED  1
+#define WGET_QUIET    2
+
+#define chunked (flags & WGET_CHUNKED)
+#define quiet   (flags & WGET_QUIET)
+
 
 #if ENABLE_FEATURE_WGET_STATUSBAR
 enum {
@@ -63,15 +71,12 @@
 
 static void progressmeter(int flag)
 {
-	/* We can be called from signal handler */
-	int save_errno = errno;
 	off_t abbrevsize;
 	unsigned since_last_update, elapsed;
 	unsigned ratio;
 	int barlength, i;
 
 	if (flag == -1) { /* first call to progressmeter */
-		start_sec = monotonic_sec();
 		lastupdate_sec = start_sec;
 		lastsize = 0;
 		totalsize = content_len + beg_range; /* as content_len changes.. */
@@ -139,18 +144,12 @@
 
 	if (flag == 0) {
 		/* last call to progressmeter */
-		alarm(0);
 		transferred = 0;
 		fputc('\n', stderr);
-	} else {
-		if (flag == -1) { /* first call to progressmeter */
-			signal_SA_RESTART_empty_mask(SIGALRM, progressmeter);
-		}
-		alarm(1);
 	}
-
-	errno = save_errno;
 }
+
+
 /* Original copyright notice which applies to the CONFIG_FEATURE_WGET_STATUSBAR stuff,
  * much of which was blatantly stolen from openssh.  */
 /*-
@@ -193,6 +192,29 @@
 #endif
 
 
+/* Perform periodic tasks during a download */
+static void timer(int flag UNUSED_PARAM)
+{
+	/* we are called from a signal handler */
+	int save_errno = errno;
+
+	if (timeout != 0) {
+		if ((start_sec + timeout) < monotonic_sec()) {
+			bb_perror_msg_and_die("download timed out");
+		}
+	}
+
+	if (!quiet) {
+		progressmeter(1);
+	}
+
+	/* re-trigger timer */
+	alarm(1);
+
+	errno = save_errno;
+}
+
+
 /* Read NMEMB bytes into PTR from STREAM.  Returns the number of bytes read,
  * and a short count if an eof or non-interrupt error is encountered.  */
 static size_t safe_fread(void *ptr, size_t nmemb, FILE *stream)
@@ -410,6 +432,7 @@
 	bool use_proxy = 1;             /* Use proxies if env vars are set  */
 	const char *proxy_flag = "on";  /* Use proxies if env vars are set  */
 	const char *user_agent = "Wget";/* "User-Agent" header field        */
+	const char *timeout_param = "0";/* Operation timeout parameter      */
 
 	static const char keywords[] ALIGN1 =
 		"content-length\0""transfer-encoding\0""chunked\0""location\0";
@@ -426,6 +449,7 @@
 		WGET_OPT_USER_AGENT = 0x40,
 		WGET_OPT_PASSIVE    = 0x80,
 		WGET_OPT_HEADER     = 0x100,
+		WGET_OPT_TIMEOUT    = 0x200,
 	};
 #if ENABLE_FEATURE_WGET_LONG_OPTIONS
 	static const char wget_longopts[] ALIGN1 =
@@ -437,6 +461,7 @@
 		"directory-prefix\0" Required_argument "P"
 		"proxy\0"            Required_argument "Y"
 		"user-agent\0"       Required_argument "U"
+		"timeout\0"          Required_argument "T"
 		"passive-ftp\0"      No_argument       "\xff"
 		"header\0"           Required_argument "\xfe"
 		;
@@ -444,6 +469,8 @@
 
 	INIT_G();
 
+	flags = 0;
+
 #if ENABLE_FEATURE_WGET_LONG_OPTIONS
 	applet_long_options = wget_longopts;
 #endif
@@ -453,13 +480,16 @@
 				&fname_out, &dir_prefix,
 				&proxy_flag, &user_agent,
 				NULL, /* -t RETRIES */
-				NULL /* -T NETWORK_READ_TIMEOUT */
+				&timeout_param
 				USE_FEATURE_WGET_LONG_OPTIONS(, &headers_llist)
 				);
 	if (strcmp(proxy_flag, "off") == 0) {
 		/* Use the proxy if necessary */
 		use_proxy = 0;
 	}
+
+	timeout = xatou(timeout_param);
+
 #if ENABLE_FEATURE_WGET_LONG_OPTIONS
 	if (headers_llist) {
 		int size = 1;
@@ -506,10 +536,15 @@
 			opt &= ~WGET_OPT_CONTINUE;
 		}
 	}
+
 #if ENABLE_FEATURE_WGET_STATUSBAR
 	curfile = bb_get_last_path_component_nostrip(fname_out);
 #endif
 
+	if (opt & WGET_OPT_QUIET) {
+		flags |= WGET_QUIET;
+	}
+
 	/* Impossible?
 	if ((opt & WGET_OPT_CONTINUE) && !fname_out)
 		bb_error_msg_and_die("cannot specify continue (-c) without a filename (-O)"); */
@@ -528,7 +563,7 @@
 	 * sites (i.e. ftp.us.debian.org) use round-robin DNS
 	 * and we want to connect to only one IP... */
 	lsa = xhost2sockaddr(server.host, server.port);
-	if (!(opt & WGET_OPT_QUIET)) {
+	if (!quiet) {
 		fprintf(stderr, "Connecting to %s (%s)\n", server.host,
 				xmalloc_sockaddr2dotted(&lsa->u.sa));
 		/* We leak result of xmalloc_sockaddr2dotted */
@@ -540,7 +575,7 @@
 		 */
 		do {
 			got_clen = 0;
-			chunked = 0;
+			flags &= ~WGET_CHUNKED;
 
 			if (!--try)
 				bb_error_msg_and_die("too many redirections");
@@ -658,7 +693,8 @@
 				if (key == KEY_transfer_encoding) {
 					if (index_in_strings(keywords, str_tolower(str)) + 1 != KEY_chunked)
 						bb_error_msg_and_die("transfer encoding '%s' is not supported", str);
-					chunked = got_clen = 1;
+					flags |= WGET_CHUNKED;
+					got_clen = 1;
 				}
 				if (key == KEY_location) {
 					if (str[0] == '/')
@@ -774,8 +810,16 @@
 		output_fd = xopen(fname_out, o_flags);
 	}
 
-	if (!(opt & WGET_OPT_QUIET))
+	start_sec = monotonic_sec();
+
+	if (!quiet) {
+		/* first call to progressmeter */
 		progressmeter(-1);
+	}
+
+	/* setup the timer */
+	signal_SA_RESTART_empty_mask(SIGALRM, timer);
+	alarm(1);
 
 	if (chunked)
 		goto get_clen;
@@ -816,8 +860,13 @@
 			break; /* all done! */
 	}
 
-	if (!(opt & WGET_OPT_QUIET))
+	/* stop timer */
+	alarm(0);
+
+	if (!quiet) {
+		/* last call to progressmeter */
 		progressmeter(0);
+	}
 
 	if ((use_proxy == 0) && target.is_ftp) {
 		fclose(dfp);
--- busybox-1.13.0.org/include/usage.h	2008-11-08 22:38:23.000000000 +0100
+++ busybox-1.13.0/include/usage.h	2008-11-18 12:05:53.000000000 +0100
@@ -4674,10 +4674,10 @@
 	USE_FEATURE_WGET_LONG_OPTIONS( \
        "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document file]\n" \
        "	[--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" \
-       "	[-U|--user-agent agent] url" \
+       "	[-U|--user-agent agent] [-T|--timeout SECONDS] url" \
 	) \
 	SKIP_FEATURE_WGET_LONG_OPTIONS( \
-       "[-csq] [-O file] [-Y on/off] [-P DIR] [-U agent] url" \
+       "[-csq] [-O file] [-Y on/off] [-P DIR] [-U agent] [-T SECONDS] url" \
 	)
 #define wget_full_usage "\n\n" \
        "Retrieve files via HTTP or FTP\n" \
@@ -4689,6 +4689,7 @@
      "\n	-O	Save to filename ('-' for stdout)" \
      "\n	-U	Adjust 'User-Agent' field" \
      "\n	-Y	Use proxy ('on' or 'off')" \
+     "\n	-T	Set timeout to SECONDS" \
 
 #define which_trivial_usage \
        "[COMMAND...]"

-- 
Matthias Kaehlcke
Embedded Linux Engineer
Barcelona

              La posibilidad de realizar un suenyo es lo
                 que hace que la vida sea interesante
                                                                 .''`.
    using free software / Debian GNU/Linux | http://debian.org  : :'  :
                                                                `. `'`
gpg --keyserver pgp.mit.edu --recv-keys 47D8E5D4                  `-



More information about the busybox mailing list