[Bug-wget] Timeouts too long?

Paul McFerrin pmcferrin@columbus.rr.com
Sat Oct 3 07:20:00 GMT 2009


I've written a small & nifty program that will terminate a command line 
after N seconds. It was written nearly 18 years ago and has served me 
very well. I'm not saying that you always live with bad program design, 
but having a solution is quite nice. The usage is:
 tcmd [-s {sig#}] [-t secs] [-x] cmd args ...
Ejoy. This one is on me.
Here is the source, compile for yourselves.
----------------------------------------------------------------
#ident "@(#)tcmd.c - NCP 1.1 08/28/91 - PEM"
/*
 Execute the command line and terminate if it does
 not complete within a specified time limit.
 Usage:
 tcmd [-s signal] [-t secs] [-x] cmd args ...
 Upon timeout, signal "signal" (default is SIGTERM) is
 sent to all children in child process group.
 Exit codes:
 0 = success
 254 = timed-out
 253 = execvp() failed for cmd
 252 = fork() failed
 251 = usage() exit
 128-146 = cmd terminated with signal 'sig - 127'
 all_others = exit status of "cmd"
 Author: Paul E. McFerrin, 55821, Aug 27, 1991
*/
#include <stdio.h>
#include <signal.h>
#include <errno.h>
extern int errno, optind;
extern char *optarg;
int tlimit; /* allowed time limit */
int ksig; /* signal to use to terminate */
int timeout(); /* alarm clock signal catcher */
int timedout; /* > 0 if execution timed out */
int childpid; /* pid of chil process */
char *cmd; /* the name of our process, argv[0] */
main( argc, argv )
int argc;
char *argv[];
{
 int xflag, opt, i, status, ws, myuid;
 myuid = getuid(); /* remember our real-uid */
 cmd = *argv; /* save our name is global area */
 tlimit = 30; /* default 30 seconds */
 ksig = SIGTERM; /* default terminate signal */
 xflag=0;
 timedout = 0;
 if( argc <= 1 ) usage(); /* no return */
 while ( (opt = getopt(argc, argv, "s:t:x")) != EOF ) {
 switch (opt) {
 case 'x' :
 xflag = 1;
 break;
 case 't' :
 tlimit = atoi(optarg);
 if( tlimit <= 0) {
 fprintf(stderr, "%s: time limit must be 
 > 0\n",
 cmd);
 usage();
 }
 break;
 case 's' :
 ksig = atoi(optarg);
 if( ksig < 1 || ksig > SIGUSR2 ) {
 fprintf(stderr, "%s: bad signal number: 
%s\n",
 cmd, optarg);
 usage();
 }
 break;
 default:
 usage();
 }
 }
 
 if( xflag ) {
 fprintf(stderr, "+ ");
 for(i=optind; i<argc; i++) {
 fprintf(stderr, "%s ", argv[i]);
 }
 fprintf(stderr, "\n");
 }
 childpid = fork();
 switch (childpid) {
 case -1 :
 fprintf(stderr, "%s: can not fork()\n", cmd);
 perror("");
 exit(252);
 break;
 case 0 : /* child */
 break;
 default : /* parent */
 signal(SIGALRM, timeout);
 signal(SIGHUP, timeout);
 signal(SIGINT, timeout);
 signal(SIGTERM, timeout);
 signal(SIGQUIT, timeout);
 signal(SIGPIPE, timeout);
 signal(SIGUSR1, timeout);
 signal(SIGUSR2, timeout);
 alarm(tlimit);
 do {
 ws = wait(&status);
 } while ( (ws != childpid) && (ws < 0 && errno == EINTR) );
 alarm(0);
 if( timedout == SIGALRM ) {
 if( xflag ) fprintf(stderr,
 "%s: Command timed-out\n", cmd);
 exit(254);
 }
 exit( (status & 255) ? status + 127 : status >> 8);
 break;
 }
/*
 * At this point, the child is executing this code. Become
 * a process group leader to that our parent can kill all
 * of our processes not known by our parent.
 */
 setuid(myuid); /* give up root access */
 setpgrp();
 execvp( argv[optind], &argv[optind] );
 fprintf( stderr, "%s: '%s' - not executed. ", cmd, argv[optind] );
 perror( "" );
 exit( 253 );
}
usage()
{
 fprintf( stderr, "Usage: %s [-t secs] [-s signal] [-x] command 
[ arg ..
. ]\n", cmd );
 exit(251);
}
/*
 * signal trap handler. If signal receive is SIGALRM then
 * we send "ksig". All other signals are sent as is to the
 * child process group leader. This permits hangups,
 * interrupts, and quits, .... to be received by the new
 * process group.
 */
timeout(sig)
int sig;
{
 timedout = sig == SIGALRM ? ksig : sig;
 if( childpid < 3 ) return; /* fail safe protection */
 kill(-childpid, timedout);
 return;
}
- Paul
Micah Cowan wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>> With Wget's default of 20 tries, and 900-second timeouts, the following
> bug report notes that Wget can sit on a download attempt for a total of
> 2.5 hours (actually, my math puts it at 5).
>> https://savannah.gnu.org/bugs/index.php?27141
>> Obviously, we can adjust these settings in wgetrc, but should that be
> necessary? Are people happy with the current timeout settings, and if
> not, what are some proposed better values?
>> - --
> Micah J. Cowan
> Programmer, musician, typesetting enthusiast, gamer.
> Maintainer of GNU Wget and GNU Teseq
> http://micah.cowan.name/
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>> iEYEARECAAYFAkrGRlcACgkQ7M8hyUobTrG18gCfTHKEcrdXrG/An2g5IM9ZPyTK
> uK0An1vJXqsSF98X8vO7MRsR+f2197Tf
> =SJkz
> -----END PGP SIGNATURE-----
>>>>
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple


More information about the Cygwin mailing list

AltStyle によって変換されたページ (->オリジナル) /