[458] in Zephyr_Bugs
Re: Zephyr on HPUX machines and possibly on AIX.
daemon@ATHENA.MIT.EDU (Scott Dawson)
Mon Mar 1 18:34:43 1993
To: zephyr-bugs@Athena.MIT.EDU
Cc: sdawson@engin.umich.edu
Date: Mon, 01 Mar 93 17:04:21 -0500
From: Scott Dawson <sdawson@engin.umich.edu>
Hi. I had a question about a week ago about zwgc on HPUX and AIX
machines. Here's my original question. I have figured out the answer,
and have posted it below.
> Hi. I have gotten zephyr running on an HP9000/720, running hpux
> V8.07. I have a problem with the way that zwgc exits. I think that
> this may be a problem on any SYSV type system which would mean that it
> would be a problem on IBM RS6000s running AIX too. The problem is
> this.
>
> When you run zwgc as I understand it, it sets itself up to die when it
> gets a SIGHUP signal. On a BSD system this happens when you log out
> and vhangup() is called. Your entire process group gets a HUP signal
> and zwgc dies. On HPUX, the termios(7) manpage states that when you log
> out, your session leader exits, and everything in its foreground process
> group gets a HUP signal. Problem is that zwgc isn't in the foreground
> process group and so it doesn't die. (If your shell is sh, then it
> will be, but if you use csh, it won't be). I think that this is
> because sh isn't doing any job control and so it isn't creating a new
> process group for each job that runs. This means that you could end
> up having lots of these running if people don't kill them on their own.
> I'd rather not have this happen.
>
> So, my questions are:
> 1. Do you either know of anybody who has this running on HPUX machines?
> 2. Has anybody encountered this type of problem with a SYSV machine?
> 3. Is there a good way to have zwgc find out who the session leader is
> and put itself into that process group?
>
> I looked at the code for things which happen specific to the AIX
> machines and signal handling, but I couldn't seem to find anything
> which seemed different as far as logging out.
>
> I've also tried asking about how to do this (set up a process to get a
> HUP upon logout) on comp.sys.hp, but I have received no answer.
>
> Thanks in advance for any info,
> -Scott Dawson
Here's my post on comp.sys.hp answering the question. It seems that
on HPUX machines you can indeed walk the ppid chain by using the
pstat() system call. You can find out who your session leader is and
put yourself in that process group. When you log out, your program
will die. I doubt this will work on IBM RS6K (zwgc doesn't die upon
logout on those either), but I will be looking into how to do that one
next.
I'll mail you guys a zwgc diff if you want when I roll this in.
-Scott
----------comp.sys.hp post follows-------------
Well, since no one helped me out on this one, I figured it out for
myself. Here's the summary, in case anyone is interested. The reason
I needed to do this was because one of the applications in Zephyr
(distributed by MIT) called zwgc, sets itself up to get killed when
you log out.
In order to get killed when you log out, zwgc depends upon getting a
HUP signal. On BSD machines this usually happens because of a vhangup()
call. On HPUX, there is no vhangup(). When you log out, you won't
get a HUP unless you are a member of the "foreground process group".
So unless your shell is /bin/sh you wont get HUP'd, because the process
group of zwgc will never be the "foreground process group". One way to
get into the foreground process group is to find out who your session
leader is and get into its group. Here's an example of a program which
will do that. It uses the undocumented (thanks HP) system call pstat()
to walk a ppid chain. For each link of the chain, it finds out the pgrp.
When it gets a -1 from getpgrp2, it knows that it has crossed the session
boundary, therefore the last pid checked must be the session leader. It
then puts itself in the process group of that session leader. When you
log out, it dies.
#include <sys/pstat.h>
main()
{
struct pst_status p;
int oldpid;
int curpid;
int found;
pid_t sessionid, pid;
curpid=getpid();
found=0;
while(!found){
(void)pstat(PSTAT_PROC,&p,sizeof(struct pst_status),0,curpid);
oldpid=curpid;
curpid=p.pst_ppid;
if(getpgrp2(curpid) < 0) found=1;
}
sessionid=getpgrp2(oldpid);
pid=fork();
if(!pid){
setpgid(0,sessionid);
sleep(3000);
}
}