Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 07 Apr 1999 21:42:29 -0400 (EDT)
From:      Simon Shapiro <shimon@simon-shapiro.org>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: wait4 - Proof I am stupid
Message-ID:  <XFMail.990407214229.shimon@simon-shapiro.org>
In-Reply-To: <199904080038.RAA07199@apollo.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help
This message is in MIME format
--_=XFMail.1.3.p0.FreeBSD:990407214229:834=_
Content-Type: text/plain; charset=us-ascii


On 08-Apr-99 Matthew Dillon wrote:
>:Hi Y'll,
>:
>:Please bear with me:
>:...
>:
>:        switch (y = wait4((-1)* my_pgid, &z, NULL)) {
>:...
>:
>:Question:  Why?  Obviously I am doing something wrong, but what?
> 
>     wait4 takes four arguments, not three.  man wait4.
> 
>     I also strongly suggest compiling with -Wall so you get
> appropriate
>     errors when you forget to include the right header files.
> 
>     Also, your code flow for fork() is dangerous, even if it is only 
>     demonstration code :-).  When you fork, the child should never
> fall 
>     through into the parents code... it should _exit(0) 
>     ( note the underscore ) before then.  You also need to make sure
> that
>     any FILE buffers are flushed before you fork to avoid a
> double-flush
>     ( where both parent and child flush the same buffered data in
> FILEs ).

I know all that, Matt. Thanx! :-)

Here is ``real'' code that compiles cleanly with -Wall. Still does the
wrong thing (for me).  The problem I am having, is that wait4() says
there are no processes to wait for, while they are there.  for sure.

In the real program, the gandchildren run, do I/O, talk to grandpa over
shared memory, get signals from grandpa, etc.  Just grandpa cannot see
them in wait4 :-(



> 
> 
>     fflush(stdout);   /* prevent double flush from occuring in child
*/
>     fflush(stderr);   /* prevent double flush from occuring in child
*/
>     if ((pid = fork()) == 0) {
>       /* child does something */
>       _exit(0);
>     }
>     if (pid == (pid_t)-1) {
>       /* fork error occured */
>       exit(1);
>     }
>     /* parent continues execution */
> 
>     To wait for the child to exit with wait4():
> 
>       if (wait4(pid, NULL, 0, NULL) < 0) {
>           /* something unexpected happened */
>       }
>       /* wait complete.  child is gone */
> 
>     If you are interested in using a more portable function, look at 
>     waitpid() rather then wait4().
> 
>       if (waitpid(pid, NULL, 0) < 0) {
>           /* something unexpected happened */
>       }
>       /* wait complete.  child is gone */
> 
>     If you want the return code:
> 
>       int status;
>       int return_code;
> 
>       if (waitpid(pid, &status, 0) < 0) {
>           /* something unexpected happened */
>       }
>       return_code = WEXITSTATUS(status);
> 
>     See 'man waitpid'.
> 
>                                       -Matt
>                                       Matthew Dillon 
>                                       <dillon@backplane.com>
> 
>:Note:  The ``code'' above is illutration only...
>:
>:Sincerely Yours,                 Shimon@Simon-Shapiro.ORG
>:                                             770.265.7340
>:Simon Shapiro
> 
> 
> 
> 
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-hackers" in the body of the message



Sincerely Yours,                 Shimon@Simon-Shapiro.ORG
                                             770.265.7340
Simon Shapiro

Unwritten code has no bugs and executes at twice the speed of mouth


--_=XFMail.1.3.p0.FreeBSD:990407214229:834=_
Content-Disposition: attachment; filename="msg.c"
Content-Transfer-Encoding: none
Content-Description: Compilable demonstration of Wai4 difficulty
Content-Type: application/octet-stream; name=msg.c; SizeOnDisk=2329

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/uio.h>
#include <limits.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

extern const char * const sys_errlist[];
extern const int sys_nerr;

int
main(int argc, char **argv)
{
		int x =0, a = 0;

		pid_t my_pgid = getpgrp();

		(void)fprintf(stderr, "grandpa grpid = %d\n", my_pgid);

		switch (fork()) {
		case 0:
				(void)setpgid(getpid(), getpid());

				my_pgid = getpgrp();

				(void)fprintf(stderr, "son: my_pgid = %d\n", my_pgid);
				
				for (x = 0; x < 10; x++) {
						switch (fork()) {
						case 0:
								/* Go do something useful */
								(void)fprintf(stderr,
											  "grandchild %d pid %d "
											  "in pgrp %d\n", x, getpid(),
											  getpgrp());
								sleep(60);
								exit(0);
								break;
						case -1:
								(void)fprintf(stderr, "failed in line %d\n",
											  __LINE__);
								exit(1);
								/* Ooops! */
								break;
						default:
								/* Ignore */
								break;
						}
				}
				
				(void)fprintf(stderr, "son exits\n");
				
				exit(0);
				break;;
		case -1:
				/* Ooops! */
				(void)fprintf(stderr, "forking the son failed (%s)\n",
							  strerror(errno));
				exit(1);
				break;
		default:
				/* ignore */
				(void)fprintf(stderr, "grandpa continues to wait loop\n");
				break;
		}

		x = 10;
		sleep(10);
		(void)fprintf(stderr, "before wait loop, x = %d\n", x);

		while (x) {
				pid_t y;
				int   z;

				(void)fprintf(stderr, "in wait loop (%d), my_pgid = %d\n",
							  ++a, my_pgid);

				switch (y = wait4((-1)* my_pgid, &z, 0, NULL)) {
				case 0:
						/* Never happens */
						(void)fprintf(stderr, "wait returned 0\n");
						if (a == 20)
								exit(2);
						break;
				case -1:
						/* ALWAYS HAPPENS */
						(void)fprintf(stderr, "wait failed (%s)\n",
									  strerror(errno));
						if (a == 20)
								exit(2);
						break;
				default:
						/* Never happens */
						(void)fprintf(stderr, "wait returned %d in pass %d\n",
									  y, x);
						--x;
						break;
				}
		}

		return(0);
}

--_=XFMail.1.3.p0.FreeBSD:990407214229:834=_--
End of MIME message


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.990407214229.shimon>