greywolf@unisoft.UUCP (The Grey Wolf) (02/13/91)
[ .globl _newsfood, 512; ] I'm doing a major upgrade to the Berkeley C shell (no flames, please; I speak csh and sh fluently and have different uses for each one). One of the things I am implementing is a "push" builtin, which is supposed to simply fork() and create an exact duplicate of the shell on top of itself. In the older version of this shell (to which I have regrettably lost the source), we used to do this for extended alterations of environment without having to restart the damn thing (i.e. aliases and shell variables were preserved). It was easier than throwing it into a ( subshell ), and we needed the interaction. Now, never mind *why* I want to do this when there might be other solutions... When the push command is entered, the following set of events occurs (assume all necessary variables): dopush() { switch (fork()) { case -1: /* error */ setname("push"); bferr("Couldn't fork!"); return (1); case 0: /* child */ /* set $$ = getpid() */ /* set process group to $$ */ /* set tty process group to $$ */ /* increment push level */ return(0); default: /* parent */ wait(&exitstat); /* reset process group */ /* reset terminal process group */ return(exitstat); } } Now, the push() occurs fine (it forks and does all the necessary stuff). HOWEVER: As soon as I hit an interrupt, the pushed shell prints a prompt, exits, and the original shell prints a prompt. The thing that's confusing is that I don't know why the pushed shell is only catching the interrupt once and then giving up. It seems as though the parent shell also gets the interrupt (which I didn't think would happen if the process group gets reset). I thought Berkeley signal handlers reset themselves...? This is a Pyramid running OSx 5.0b, under the BSD universe (essentially BSD 4.2-and-a-half). -- thought: I ain't so damb dumn! | Your brand new kernel just dump core on you war: Invalid argument | And fsck can't find root inode 2 | Don't worry -- be happy... ...!{ucbvax,acad,uunet,amdahl,pyramid}!unisoft!greywolf