jonathan@comp.vuw.ac.nz (Jonathan) (10/06/88)
Enclosed are fixes for two Amoeba problems. They are applicable to either 1.3b or 1.3c. I mailed these to Dr. Tanenbaum months ago; it seems he never got them. Client3.c as posted never worked for me; the context diff below fixes the bogus parentheses. Master.c misbehaves chronically if for some reason the exec in its child fails. It produced an error message, the child exited, and then master creates a new child whose exec fails... The error messages came so rapidly I couldn't do *anything*, and had to cycle the power. The replacement master.c avoids the problem by waiting after a failed exec. Enjoy - Jonathan. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # client3.c.cdif # master.c # master.c~ # This archive created: Thu Oct 6 13:28:50 1988 # By: Jonathan () export PATH; PATH=/bin:$PATH echo shar: extracting "'client3.c.cdif'" '(791 characters)' if test -f 'client3.c.cdif' then echo shar: will not over-write existing file "'client3.c.cdif'" else sed 's/^X//' << \SHAR_EOF > 'client3.c.cdif' X*** client3.c.orig Wed Aug 24 20:58:45 1988 X--- client3.c Wed Aug 24 21:54:13 1988 X*************** X*** 140,146 **** X if (n < 0) {errno = EIO; return(ER);} X if (hdr2.h_extra != 0) errno = hdr2.h_extra; X pos[fd] += hdr2.h_status; /* advance file position */ X! return(hdr2.h_status); X } X X X--- 140,146 ---- X if (n < 0) {errno = EIO; return(ER);} X if (hdr2.h_extra != 0) errno = hdr2.h_extra; X pos[fd] += hdr2.h_status; /* advance file position */ X! return((int) hdr2.h_status); X } X X X*************** X*** 225,231 **** X } X X do { X! if ((n=read(fd1, b, 1024) < 0)) { X printf("Cannot read %s\n", argv[1]); X exit(1); X } X--- 225,231 ---- X } X X do { X! if ((n=read(fd1, b, 1024)) < 0) { X printf("Cannot read %s\n", argv[1]); X exit(1); X } SHAR_EOF if test 791 -ne "`wc -c < 'client3.c.cdif'`" then echo shar: error transmitting "'client3.c.cdif'" '(should have been 791 characters)' fi fi # end of overwriting check echo shar: extracting "'master.c'" '(1454 characters)' if test -f 'master.c' then echo shar: will not over-write existing file "'master.c'" else sed 's/^X//' << \SHAR_EOF > 'master.c' X#include <signal.h> X Xchar console[] = "/dev/tty0"; /* no "/dev/console" on Minix */ X Xrun(uid, gid, argv) Xchar **argv; X{ X int status; X X for (;;) X#ifdef DEBUG X sleep (2); X#endif DEBUG X switch (fork()) { X default: X return; X case 0: X if ((status = setgid(gid)) < 0) X perror ("setting gid"); X if ((status = setuid(uid)) < 0) X perror ("setting uid"); X/* X execvp(*argv, argv); X*/ X execv(*argv, argv); X perror("master: exec'ing"); X printf("can't execute %s\n", *argv); X/* X kill(getppid(), SIGTERM); X*/ X /* If the exec failed, don't try it again X * immediately. Give the kernel X * a chance to do something else X */ X sleep (5); X _exit(1); X case -1: X sleep(10); X } X} X Xmain(argc, argv) Xchar **argv; X{ X register n, uid, gid; X X /* Minix can't do this X setpgrp(getpid(), getpid()); X */ X if (argc < 4) { X prints("Usage: master # uid gid command args ...\n"); X return(1); X } X n = atoi(argv[1]); X if (n < 1 || n > 20) { X prints("Bad count.\n"); X return(1); X } X signal(SIGHUP, SIG_IGN); X signal(SIGINT, SIG_IGN); X signal(SIGQUIT, SIG_IGN); X X/* Put the program into the background. */ X switch (fork()) { X case 0: X break; X case -1: X perror(argv[0]); X return 1; X default: X return 0; X } X uid = atoi(argv[2]); X gid = atoi(argv[3]); X X/* Start n copies of the program. */ X do X run(uid, gid, &argv[4]); X while (--n); X X/* Replace each one that dies. */ X while (wait((int *) 0) > 0) X run(uid, gid, &argv[4]); X return(0); X} SHAR_EOF if test 1454 -ne "`wc -c < 'master.c'`" then echo shar: error transmitting "'master.c'" '(should have been 1454 characters)' fi fi # end of overwriting check echo shar: extracting "'master.c~'" '(1423 characters)' if test -f 'master.c~' then echo shar: will not over-write existing file "'master.c~'" else sed 's/^X//' << \SHAR_EOF > 'master.c~' X#include <signal.h> X Xchar console[] = "/dev/console"; X Xrun(uid, gid, argv) Xchar **argv; X{ X int status; X X for (;;) X#ifdef DEBUG X sleep (2); X#endif DEBUG X switch (fork()) { X default: X return; X case 0: X if ((status = setgid(gid)) < 0) X perror ("setting gid"); X if ((status = setuid(uid)) < 0) X perror ("setting uid"); X/* X execvp(*argv, argv); X*/ X execv(*argv, argv); X perror("master: exec'ing"); X printf("can't execute %s\n", *argv); X/* X kill(getppid(), SIGTERM); X*/ X /* If the exec failed, don't try it again X * immediately. Give the kernel X * a chance to do something else X */ X sleep (5); X _exit(1); X case -1: X sleep(10); X } X} X Xmain(argc, argv) Xchar **argv; X{ X register n, uid, gid; X X /* Minix can't do this X setpgrp(getpid(), getpid()); X */ X if (argc < 4) { X prints("Usage: master # uid gid command args ...\n"); X return(1); X } X n = atoi(argv[1]); X if (n < 1 || n > 20) { X prints("Bad count.\n"); X return(1); X } X signal(SIGHUP, SIG_IGN); X signal(SIGINT, SIG_IGN); X signal(SIGQUIT, SIG_IGN); X X/* Put the program into the background. */ X switch (fork()) { X case 0: X break; X case -1: X perror(argv[0]); X return 1; X default: X return 0; X } X uid = atoi(argv[2]); X gid = atoi(argv[3]); X X/* Start n copies of the program. */ X do X run(uid, gid, &argv[4]); X while (--n); X X/* Replace each one that dies. */ X while (wait((int *) 0) > 0) X run(uid, gid, &argv[4]); X return(0); X} SHAR_EOF if test 1423 -ne "`wc -c < 'master.c~'`" then echo shar: error transmitting "'master.c~'" '(should have been 1423 characters)' fi fi # end of overwriting check # End of shell archive exit 0 -- ----------------------------------------------------------------------------- sane mailers: jonathan@comp.vuw.ac.nz | Industrial democracy: UUCP path: ...!uunet!vuwcomp!jonathan | One factory, one vote!