Starting Remote Jobs

Chris Torek chris at mimsy.UUCP
Wed May 10 22:51:30 AEST 1989


In article <815 at usl.usl.edu> pcb at usl.usl.edu (Peter C. Bahrs) writes:
>How can I start a remote background job?
>
>I have tried:
>  rsh machine 'program &'     this waits on my local machine for termination

Not exactly.  Rather, it waits on your local machine for end-of-file
(for the `pipe' [socket] it opens to the remote machine to indicate
that that program is done sending output back).  What you must do, then,
is convince `program' to close all its open file descriptors (which are
dup()s of that socket) before doing anything else.  If your remote shell
is `sh':

	rsh machine 'exec program </dev/null >/dev/null 2>&1 &'

If your remote shell is `csh':

	rsh machine 'exec program </dev/null >&/dev/null &'

If your remote shell is unknown:

	rsh machine 'quietly exec program'
	# program is run by sh, may contain redirections, etc.

where `quietly' is as shown below (comments left as an exercise to the
reader :-) ).  N.B.: if you do not have strerror(), complain to your
vendor and/or use

	char *strerror(e) int e; {
		static char u[40];
		extern int sys_nerr;
		extern char *sys_errlist[];

		if ((unsigned)e >= sys_nerr) {
			(void) sprintf(u, "unknown error code %d", e);
			return (u);
		}
		return (sys_errlist[e]);
	}

(if it works, put it in your C library).

#include <stdio.h>

extern int errno;
char	*strcpy(), *strerror(), *malloc();

char	*copy();

main(argc, argv)
	int argc;
	char **argv;
{
	char *cmd;

	if (argc < 2) {
		fprintf(stderr, "usage: quietly prog [args ...]\n");
		exit(2);
	}
	cmd = copy(argc - 1, argv + 1);
	switch (fork()) {
	case 0:
		closeall();
		execl("/bin/sh", "sh", "-c", cmd, (char *)NULL);
		_exit(1);	/* cannot complain anymore */
		/* NOTREACHED */
	case -1:
		fprintf(stderr, "quietly: cannot fork: %s\n", strerror(errno));
		exit(1);
	/* default: parent */
	}
	exit(0);
}

closeall()
{
	register int i;

	for (i = getdtablesize(); --i >= 0;)
		(void) close(i);
}

char *
copy(ac, av)
	int ac;
	char **av;
{
	register char **p, *m;
	register int l = 0, n;

	for (p = av, n = ac; --n >= 0;)
		l += strlen(*p++) + 1;
	if ((m = malloc((unsigned)l)) == NULL) {
		fprintf(stderr, "quietly: cannot allocate %d bytes: %s\n",
			l, strerror(errno));
		exit(1);
	}
	for (p = av, n = ac; --n >= 0;) {
		m += strlen(strcpy(m, *p++));
		*m++ = ' ';
	}
	m[-1] = '\0';
	return (m - l);
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.unix.questions mailing list