funny SIGCHLD behavior




Hello all,

I'm trying to implement a simple shell (as below) and am facing some
funny behavior. Hoping one of you has some ideas.

The behavior I see is:
bash $ ./sh
$ /bin/sleep 4 &
job 97705 (/bin/sleep) started in background
back to loop
$ ls
sh.c jobs.c sh.h Makefile
back to loop
$ chewba
job: pid 97705 finished
done, exit
bash $ chewba ## I typed this into my program!
bash $

My questions:
1. I think I have set up the signal handlers correctly i.e. every
SIGCHLD must get sent to the handler. Also, the handler is supposed to
return to the main prog, right? Instead, the main prog just exits!
2. I've tried doing the same thing below by writing a small program
like so:
/* set up signal handler exactly like below */
while (i++ < 10)
{
if ((pid = fork()) == 0) { execv(cpu_stress[0], cpu_stress); }
}

do {
printf(" enter a number\n"); scanf("%d", i);
} while (i != -1);
exit(0);
3. In the program above, cpu_stress refers to a non-interactive
program that does some computation (1million sin(x) calculations) and
simply exits. The handler handles all those children exiting. In the
meantime, I still get to enter numbers to the do { } loop until I want
to exit.
4. So then, why does my shell exit involuntarily while the same code
in the test program seems to behave ok? I mean, my shell is in the
middle of reading my next command (chewbacca) and it just, well,
quits.

I've spent about half a day reading through manuals and the web, but
this is truly confounding me! Appreciate any suggestions from ye gurus
out there.

-SNS
---------------

main()
{
/* basic bookeeping */
init_jobs();
/* init_jobs is declared and defined in another file jobs.c
* it does the following:
*
* sigemptyset( & (handler_action.sa_mask) );
* sigaddset( & (handler_action.sa_mask), SIGINT );
* sigaddset( & (handler_action.sa_mask), SIGQUIT );
* handler_action.sa_flags = SA_SIGINFO;
* handler_action.sa_sigaction = handle_reap;
*
* sigaction (SIGCHLD, &handler_action, (struct sigaction *)0);
*
* and handle_reap(), also in jobs.c, uses this loop
*
* while ( (pid = waitpid(-1, &status, WNOHANG)) > 0 )
* {
* if (pid != 0) printf("\n job %d finished\n", pid);
* }
*/

/* readcmd() uses getc(stdin) repeatedly to build up
* cmdbuf as required by execv() functions
*/
char **cmdbuf;
while ((cmdbuf = readcmd()) != EOF)
exec_cmd(cmdbuf);

printf(" done, exit\n");
exit(0);
}

exec_cmd(char **cmdbuf)
{
/* more housekeeping */

if (is_background_job(cmdbuf))
{
if ( (pid = fork()) == 0)
{ execv(cmdbuf[0], cmdbuf); }
else
{ printf(" job %d (%s) started in background\n", pid, cmdbuf[0]); }
}
else /* assume foreground job */
{
if ( (pid = fork()) == 0)
{ execv(cmdbuf[0], cmdbuf); }
else
{ status = 0; w = wait(&status); }
}
printf("back to loop\n");
return;
}
.



Relevant Pages

  • Re: shell error codes
    ... > I agree to that when a program is launched by the shell. ... The only standardized exit codes are 126 and 127 ... SUS> If the execvefunction fails due to an error equivalent to ... program returned exit code 127 or the command was not ...
    (comp.unix.shell)
  • Re: Infinite Loop in ErrorHandler That Requires Hard Shutdown
    ... > others and have come up with the following Exit Handler and Error ... > If bInTrans Then 'Rollback if the transaction is active. ... > I thought I was handling my Error Handling and Exit Handling ...
    (microsoft.public.access.formscoding)
  • Re: cant cleanly exit shell from FC5 rescue CD
    ... When I type in 'exit' and hit enter, ... type 'linux rescue' at the prompt and hit ENTER ... at the shell prompt, ...
    (Fedora)
  • Re: Threading Issues (If you can answer this, Ill kiss you.)
    ... sent it is not read from the message queue and your SessionEnding handler is ... On the other hand when you register for the process exit event the system ... process exits a threadpool thread then calls your event handler. ... specifically to handle the broadcast messages. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: CreateProcess not working as doc specifies.
    ... > be properly maintained running through cmd.exe. ... Have you looked at the EXIT command? ... a smart wrapper for CreateProcess() will consider shell vs spawns. ...
    (microsoft.public.win32.programmer.kernel)