On Fri, Jun 16, 2017 at 02:36:03PM +0000, Luke Small wrote:
> I had it where it made a pipe and the child waited on a recv() before the
> parent registered the kevent and closed the pipe. On my virtual machine,
> this code works the same. It spawns a fork() error and my large project
> makes it where no roxterm can spawn a new ksh instance.
You might have created a fork bomb with other code, but that is is not
what your example code is doing.
Note that the bugs@ mailing list is for bug reporing. In your case it
does sound more like you need to coding help.
-Otto
> On Fri, Jun 16, 2017 at 9:20 AM Otto Moerbeek <[email protected]> wrote:
>
> > On Fri, Jun 16, 2017 at 08:16:19AM +0000, Luke Small wrote:
> >
> > > I made a simple case. I need to have a kevent wait for both incoming
> > socket
> > > communications and for the forked process to finish its run evaluating
> > > shared data.
> > > I show that it fails to merely wait for NOTE_EXIT calls and I'd guess
> > > making the kernel aware that the process died.
> > >
> > > limit_test.c shows that there is a fork error when it runs a while even
> > if
> > > it waits for the forked process to die, where it doesn't occur by simply
> > > using wait(2), which is in comments below it.
> >
> > I do not see a fork error, but a kevent error:
> >
> > ...
> > 24
> > 25
> > a.out: kevent: No such process
> >
> > You code indeed has a race condition: the child proces might already
> > have exited the moment you call kevent.
> >
> > wait(2) is a bit different: it allows for waiting on a proces that already
> > has died but hasn't been waited for yet. The child process will have the
> > zombie state in the meantime.
> >
> > -Otto
> >
> >
> > > #include <err.h>
> > > #include <stdio.h>
> > > #include <stdlib.h>
> > > #include <unistd.h>
> > > #include <sys/event.h>
> > > #include <sys/socket.h>
> > > #include <sys/wait.h>
> > >
> > > int main()
> > > {
> > > int i;
> > > int k;
> > > int kq;
> > > int integer;
> > > struct kevent ke;
> > >
> > > kq = kqueue();
> > > if (kq == -1)
> > > err(1, "kq!");
> > >
> > > for (i = 0; i < 2000; ++i)
> > > {
> > >
> > > integer = fork();
> > > switch(integer)
> > > {
> > > case -1:
> > > err(1, "fork!");
> > > case 0:
> > > _exit(0);
> > > default:
> > > break;
> > > }
> > >
> > > EV_SET(&ke, integer, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT,
> > 0, NULL);
> > > if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
> > > err(1, "kevent");
> > >
> > >
> > > k = kevent(kq, NULL, 0, &ke, 1, NULL);
> > > if (k == -1)
> > > err(1, "k == -1");
> > > if(ke.flags & EV_ERROR)
> > > err(1, "EV_ERROR");
> > >
> > > printf("%d\n", i);
> > > }
> > > }
> > >
> > > /*
> > > int main()
> > > {
> > > int i;
> > > int integer;
> > > for (i = 0; i < 2000; ++i)
> > > {
> > > integer = fork();
> > > switch(integer)
> > > {
> > > case -1:
> > > err(1, "fork!");
> > > case 0:
> > > _exit(0);
> > > default:
> > > break;
> > > }
> > > wait(NULL);
> > > printf("%d\n", i);
> > > }
> > > }
> > > */
> >
> >