Пример #1
0
int main(int argc, char **argv)
{
	char	*Argv0 = *argv;
	int	rc;
	int	lfd;
	pid_t	childpid;
	time_t	starttime;
	int	attempts = 0;

	UNUSED_PARAMETER(argc);

	time(&starttime);

	for ( argv++ ; *argv ; argv++ )
	{
		char    *arg = *argv;
		char	*opt = strchr(arg, '=');

		/* the -- token marks the end of the list */

		if ( strcmp(*argv, "--") == 0 )
		{
			argv++;
			break;
		}

		if (opt) *opt++ = '\0'; /* pick off the =VALUE part */

		if ( STRMATCH(arg, "--version") )
		{
			puts(Version);
			exit(EXIT_SUCCESS);
		}

		else if ( STRMATCH(arg, "--help"))
		{
			show_help(helptext);
			exit(EXIT_SUCCESS);
		}

		else if ( STRMATCH(arg, "-L") || STRMATCH(arg, "--lockfile"))
		{
			lockfile = getarg(opt, &argv);
		}

		else if ( STRMATCH(arg, "-W") || STRMATCH(arg, "--wait"))
		{
			wait_for_lock = TRUE;
		}

		else if ( STRMATCH(arg, "-S") || STRMATCH(arg, "--sleep"))
		{
			sleeptime = atoi(getarg(opt, &argv));
		}

		else if ( STRMATCH(arg, "-R") || STRMATCH(arg, "--retries"))
		{
			retries = atoi(getarg(opt, &argv));
		}

		else if ( STRMATCH(arg, "-T") || STRMATCH(arg, "--maxtime"))
		{
			Maxtime = atoi(getarg(opt, &argv));
		}

		else if ( STRMATCH(arg, "-V") || STRMATCH(arg, "--verbose"))
		{
			Verbose++;
		}

		else if ( STRMATCH(arg, "-Q") || STRMATCH(arg, "-q") || STRMATCH(arg, "--quiet") || STRMATCH(arg, "-I") || STRMATCH(arg, "--idempotent"))
		{
			Quiet = TRUE;
		}

		else
		{
			die("ERROR: \"%s\" is an invalid cmdline param", arg);
		}
	}

	/*----------------------------------------------------------------
	 * SANITY CHECKING
	 *
	 * Make sure that we have all the parameters we require
	 */
	if (*argv == 0)
		die("ERROR: missing command to %s (must follow \"--\" marker) ", Argv0);

	if (lockfile == 0)
		die("ERROR: missing --lockfile=F parameter");

	/*----------------------------------------------------------------
	 * Open or create the lockfile, then try to acquire the lock. If
	 * the lock is acquired immediately (==0), then we're done, but
	 * if the lock is not available, we have to wait for it.
	 *
	 * We can either loop trying for the lock (for --wait), or exit
	 * with error.
	 */

	if ( (lfd = open(lockfile, O_RDWR|O_CREAT, openmode)) < 0)
		die("ERROR: cannot open(%s) [err=%s]", lockfile, strerror(errno));

	while ( WAIT_AND_LOCK(lfd) != 0 )
	{
		attempts++;

		if ( ! wait_for_lock )
		{
			if ( Quiet)
				exit(EXIT_SUCCESS);
			else
				die("ERROR: cannot launch %s - run is locked", argv[0]);
		}

		if ( retries > 0 && attempts >= retries )
		{
			die("ERROR: cannot launch %s - run is locked (after %d attempts)", argv[0], attempts);
		}

		/* waiting */
 		if ( Verbose ) printf("(locked: sleeping %d secs, after attempt #%d)\n", sleeptime, attempts);

		sleep(sleeptime);
	}

	fflush(stdout);

	/* run the child */


	if ( (childpid = fork()) == 0 )
	{
		/* IN THE CHILD */

		close(lfd);		/* don't need the lock file */

		/* Make ourselves a process group leader so that this and all
		 * child processes can be sent a signal as a group. This may
		 * be used someday to support a --kill option, though this is
		 * is still tricky.
		 *
		 * PORTING NOTE: if "setsid" is undefined on your platform,
		 * just comment it out and send me an email with info about
		 * the build environment.
		 */
		(void) setsid();

		/* Set rc to the result of execvp. This lets the parent know we failed. */
		rc = execvp(argv[0], argv);
	}
	else if ( childpid > 0 )
	{
		/* IN THE PARENT */

		time_t endtime;
		pid_t  pid;
		int    status;

		if ( Verbose )
		    printf("Waiting for process %ld\n", (long) childpid);

		pid = waitpid(childpid, &status, 0);
		rc = WEXITSTATUS(status);

		time(&endtime);

		endtime -= starttime;

		if ( Verbose || (Maxtime > 0  &&  endtime > Maxtime) )
		    printf("pid %d exited with status %d, exit code: %d (time=%ld sec)\n",
			   pid, status, rc, endtime);
	}
	else
	{
		die("ERROR: cannot fork [%s]", strerror(errno));
	}

	exit(rc);
}
Пример #2
0
int main(int argc, char **argv)
{
	char	*Argv0 = *argv;
	int	rc;
	int	lfd;
	pid_t	childpid;
	time_t	starttime;

	UNUSED_PARAMETER(argc);

	time(&starttime);

	for ( argv++ ; *argv ; argv++ )
	{
		char    *arg = *argv;
		char	*opt = strchr(arg, '=');

		/* the -- token marks the end of the list */

		if ( strcmp(*argv, "--") == 0 )
		{
			argv++;
			break;
		}

		if (opt) *opt++ = '\0'; /* pick off the =VALUE part */

		if ( STRMATCH(arg, "-L") || STRMATCH(arg, "--lockfile"))
		{
			lockfile = getarg(opt, &argv);
		}

		else if ( STRMATCH(arg, "-W") || STRMATCH(arg, "--wait"))
		{
			wait_for_lock = TRUE;
		}

		else if ( STRMATCH(arg, "-S") || STRMATCH(arg, "--sleep"))
		{
			sleeptime = atoi(getarg(opt, &argv));
		}

		else if ( STRMATCH(arg, "-T") || STRMATCH(arg, "--maxtime"))
		{
			Maxtime = atoi(getarg(opt, &argv));
		}

		else if ( STRMATCH(arg, "-V") || STRMATCH(arg, "--verbose"))
		{
			Verbose++;
		}

		else
		{
			die("ERROR: \"%s\" is an invalid cmdline param", arg);
		}
	}

	/*----------------------------------------------------------------
	 * SANITY CHECKING
	 *
	 * Make sure that we have all the parameters we require
	 */
	if (*argv == 0)
		die("ERROR: missing command to %s (must follow \"--\" marker) ", Argv0);

	if (lockfile == 0)
		die("ERROR: missing --lockfile=F parameter");

	/*----------------------------------------------------------------
	 * Open or create the lockfile, then try to acquire the lock. If
	 * the lock is acquired immediately (==0), then we're done, but
	 * if the lock is not available, we have to wait for it.
	 *
	 * We can either loop trying for the lock (for --wait), or exit
	 * with error.
	 */

	if ( (lfd = open(lockfile, O_RDWR|O_CREAT, openmode)) < 0)
		die("ERROR: cannot open(%s) [err=%s]", lockfile, strerror(errno));

	while ( WAIT_AND_LOCK(lfd) != 0 )
	{
		if ( ! wait_for_lock )
		{
			die("ERROR: cannot launch %s - run is locked", argv[0]);
		}

		/* waiting */
		if ( Verbose ) printf("(locked: sleeping %d secs)\n", sleeptime);

		sleep(sleeptime);
	}

	fflush(stdout);

	/* run the child */


	if ( (childpid = fork()) == 0 )
	{
		close(lfd);		// don't need the lock file

		execvp(argv[0], argv);
	}
	else if ( childpid > 0 )
	{
		time_t endtime;
		pid_t  pid;

		if ( Verbose )
		    printf("Waiting for process %ld\n", (long) childpid);

		pid = waitpid(childpid, &rc, 0);

		time(&endtime);

		endtime -= starttime;

		if ( Verbose || (Maxtime > 0  &&  endtime > Maxtime) )
		    printf("pid %d exited with status %d (time=%ld sec)\n", pid, rc, endtime);
	}
	else
	{
		die("ERROR: cannot fork [%s]", strerror(errno));
	}

	exit(rc);
}