Unix Technical Forum

Start scripts under linux

This is a discussion on Start scripts under linux within the Linux Operating System forums, part of the Unix Operating Systems category; --> Peter T. Breuer wrote: > Jon Gomez <jon.gomez.04@cnu.edu> wrote: >> I will do more studying (give me a few ...


Go Back   Unix Technical Forum > Unix Operating Systems > Linux Operating System

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #11 (permalink)  
Old 01-18-2008, 06:01 AM
Jon Gomez
 
Posts: n/a
Default SIGHUP and Session leaders (was Re: Start scripts under linux)

Peter T. Breuer wrote:
> Jon Gomez <jon.gomez.04@cnu.edu> wrote:
>> I will do more studying (give me a few days), and get back to

>
> Just testing is required - really! Tell me the results! I would like to
> know what you see.


Okay, I finally wrote out a test program. Sorry for taking so long. The
following attempts to become the new session leader, spawn a child process
and die. I set it as the login shell for a local account, and did the
following tests:

1) Use su to enter the account. Result: child survived.
2) Use console login to enter the account. Result: child died?

Please read over the code carefully, if you wish to use it. It is doing
some low-level stuff (haven't tested which uid it uses as a user shell).

This is not a conclusive test. Now we need to set up signal handlers, etc.

At the bottom of this post are two references that might also be of use to
you.

//session.c

#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>

#ifndef _POSIX_JOB_CONTROL
#error POSIX job control is not enabled on the build system.
#endif

#define CHILD "/bin/cat"
#define LOGFILE "/tmp/sessiontest"

int main() {

pid_t my_pid; /* This program's process id */
pid_t my_pgid; /* This program's process group id */
pid_t session_pgid; /* process group id of the current session
leader */
pid_t fork_pid; /* PID returned by fork() */

/* Open a logfile. (FIXME)*/
if(!freopen(LOGFILE, "w", stdout)) {
fprintf(stderr, "Error: Couldn't open logfile");
usleep(1000);
exit(1);
}
/* For convenience */
fclose(stderr);
stderr = stdout;


/* Get and print current ID's */
my_pid = getpid();
my_pgid = getpgrp();
session_pgid = getsid(0);
printf("My pid: %d\n", my_pid);
printf("My pgid: %d\n", my_pgid);
printf("Session pgid: %d\n", session_pgid);

/* Sanity Check: Get session leader's pgid. Compare with our pgid. */
if(session_pgid == my_pgid)
printf("Warning: sess pgid = my pgid. Setsid() will fail!\n"
"Warning: Assuming that I am the session leader.\n");
else {
/* Take over the session */
session_pgid = setsid();
if(session_pgid == -1) {
perror("Couldn't become the new session leader");
exit(1);
}
}

/* Print new session pgid just in case */
session_pgid = getsid(0);
printf("Became new session leader with session pgid: %d\n", session_pgid);

/* Fork a new process */
printf("Creating a new child process\n");
fork_pid = fork();
if(fork_pid == -1) {
perror("Couldn't create a child process");
exit(1);
}


/* Are we the child? */
if(fork_pid == 0) {
while(1) { usleep(1000); }
}
else return 0;

}


___________________
I found some new references:

About SIGHUP and parent process death:
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC25

General information about sessions, pgid, pids:
http://www.unix.org.ua/orelly/networ...P-C-SECT-1.3.4


Jon.


-- * Does the walker choose the path, or does the path choose the walker?
(fr. Sabriel) * --
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #12 (permalink)  
Old 01-18-2008, 06:01 AM
Peter T. Breuer
 
Posts: n/a
Default Re: SIGHUP and Session leaders (was Re: Start scripts under linux)

Jon Gomez <jon.gomez.04@cnu.edu> wrote:
> Peter T. Breuer wrote:
> > Jon Gomez <jon.gomez.04@cnu.edu> wrote:
> >> I will do more studying (give me a few days), and get back to

> >
> > Just testing is required - really! Tell me the results! I would like to
> > know what you see.

>
> Okay, I finally wrote out a test program. Sorry for taking so long. The
> following attempts to become the new session leader, spawn a child process
> and die. I set it as the login shell for a local account, and did the
> following tests:
>
> 1) Use su to enter the account. Result: child survived.
> 2) Use console login to enter the account. Result: child died?


Set the variables in your shell equally. And note who is the session
leader.

It doesn't require your code to check.

main() {
if (fork()) {
sleep(1);
printf("parent dies\n");
exit(0);
}
printf ("child %d lives\n", getpid());
while (1) {
sleep(1);
}
}

That's all! Now launch the program. Then log out of (or kill, with -9)
the xterm you are in, which should be the session leader (the results
may be different since gentle logout allows the shell to send HUP to its
children if it is set to send HUP on its own death). Then look in the
process table. I see the program continuing just fine:

% pstree
init-+-a.out <- here
|-aio/0
|-apmd
...





> /* Sanity Check: Get session leader's pgid. Compare with our pgid. */
> if(session_pgid == my_pgid)
> printf("Warning: sess pgid = my pgid. Setsid() will fail!\n"
> "Warning: Assuming that I am the session leader.\n");


I didn't bother. You can check that with ps. If you don't know you
shouldn't be running the test!


> ___________________
> I found some new references:




> About SIGHUP and parent process death:
> http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC25


1.15 Why doesn't my process get SIGHUP when its parent dies?

Because it's not supposed to.

SIGHUP is a signal that means, by convention, "the terminal line got
hung up". It has nothing to do with parent processes, and is usually
generated by the tty driver (and delivered to the foreground process
group).

However, as part of the session management system, there are exactly
two cases where SIGHUP is sent on the death of a process:

* When the process that dies is the session leader of a session
* that is attached to a terminal device, SIGHUP is sent to all
* processes in the foreground process group of that terminal
* device.

In other words, when your xterm dies. But only to FOREGROUND processes,
naturally! There will be exactly one of those (well, plus whatever it
is running, and whatever it is running ...), and it will be your
shell in the xterm.

This is exactly what you expect. Your shell is notified that its xterm
has died and it should go away now.

* When the death of a process causes a process group to become
* orphaned, and one or more processes in the orphaned group are
* stopped, then SIGHUP and SIGCONT are sent to all members of the
* orphaned group. (An orphaned process group is one where no
* process in the group has a parent which is part of the same
* session, but not the same process group.)

Incomprehensible.


> General information about sessions, pgid, pids:
> http://www.unix.org.ua/orelly/networ...P-C-SECT-1.3.4
>
>
> Jon.
>
>
> -- * Does the walker choose the path, or does the path choose the walker?
> (fr. Sabriel) * --


--
---------------------------------------------------------------------
Peter T. Breuer MA CASM PhD. Ing., Prof. Ramon y Cajal
Area de Ingenieria Telematica E-mail: ptb@it.uc3m.es
Dpto. Ingenieria Tel: +34 91 624 91 80
Universidad Carlos III de Madrid Fax: +34 91 624 94 30/65
Butarque 15, E-28911 Leganes URL: http://www.it.uc3m.es/~ptb
Spain
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #13 (permalink)  
Old 01-18-2008, 06:01 AM
Peter T. Breuer
 
Posts: n/a
Default Re: SIGHUP and Session leaders (was Re: Start scripts under linux)

Peter T. Breuer <ptb@lab.it.uc3m.es> wrote:
> > 1) Use su to enter the account. Result: child survived.
> > 2) Use console login to enter the account. Result: child died?

>
> Set the variables in your shell equally. And note who is the session
> leader.
>
> It doesn't require your code to check.
>
> main() {
> if (fork()) {
> sleep(1);
> printf("parent dies\n");
> exit(0);
> }
> printf ("child %d lives\n", getpid());
> while (1) {
> sleep(1);
> }
> }
>
> That's all! Now launch the program. Then log out of (or kill, with -9)
> the xterm you are in, which should be the session leader (the results
> may be different since gentle logout allows the shell to send HUP to its
> children if it is set to send HUP on its own death). Then look in the
> process table. I see the program continuing just fine:
>
> % pstree
> init-+-a.out <- here
> |-aio/0
> |-apmd
> ...
>


I'll add that a little playing with ps -o pid,ppid,pgid,sid tells me
that

1) the session leader is the shell run BY an xterm
2) the xterm belongs to the same session as the shell it is run FROM.

Ditto process group, as far as I can see.

So when you fork a process (i.e. in background) from a foreground
process in a shell within an xterm, it should have the process group and
the session group of the shell, which the shell leads.

When its parent dies and control returns to the shell (prompt), then the
surviving process is inherited by init and its parent changes to 1,
while its process group remains that of the (dead) parent that launched
it. Its session group remains that of the shell.

Its session leader has not died and so it should not and does not get
HUP at that point.

If now you kill the xterm (or the shell), then the shell dies and

A) IF it is set to send sighup to children does so
(which does not include the process inherited by init!)
B) sighup is sent to the process group of the shell
(which doesn't include the process you forked).

So I don't see how one should ever expect that such a process would die.

Usually anyway when forking a daemon process one takes pains to set its
process group away from what it was so that it won't be associated with
the tty it was launched from, and won't receive signals from it and
won't block on input or output from/to it.


Peter
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #14 (permalink)  
Old 01-18-2008, 06:02 AM
Jon Gomez
 
Posts: n/a
Default Re: SIGHUP and Session leaders (was Re: Start scripts under linux)

Peter T. Breuer wrote:
> It doesn't require your code to check.


Nope, not if we agree.

> That's all! Now launch the program. Then log out of (or kill, with -9)
> the xterm you are in, which should be the session leader (the results
> may be different since gentle logout allows the shell to send HUP to its
> children if it is set to send HUP on its own death). Then look in the
> process table. I see the program continuing just fine


xterm doesn't appear to be the session leader, at least not on my kde. Do a
"ps -e -o sess,cmd". I think you need to kill one of the kde apps. Shall
we test this?

> I didn't bother. You can check that with ps. If you don't know you
> shouldn't be running the test!


You mean run another command? I'm too lazy ;-)

> * When the process that dies is the session leader of a session
> * that is attached to a terminal device, SIGHUP is sent to all
> * processes in the foreground process group of that terminal
> * device.
>
> In other words, when your xterm dies. But only to FOREGROUND processes,
> naturally! There will be exactly one of those (well, plus whatever it
> is running, and whatever it is running ...), and it will be your
> shell in the xterm.


Well, at least we agree that the SIGHUP is not *initially* generated by the
shell?

> This is exactly what you expect. Your shell is notified that its xterm
> has died and it should go away now.
>
> * When the death of a process causes a process group to become
> * orphaned, and one or more processes in the orphaned group are
> * stopped, then SIGHUP and SIGCONT are sent to all members of the
> * orphaned group. (An orphaned process group is one where no
> * process in the group has a parent which is part of the same
> * session, but not the same process group.)
>
> Incomprehensible.


Hmmm... Just darn specialized wording. Come to think of it, I think that
particular behaviour is obsolete by POSIX, no?


Jon.
-- * Does the walker choose the path, or does the path choose the walker?
(fr. Sabriel) * --
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #15 (permalink)  
Old 01-18-2008, 06:02 AM
Jon Gomez
 
Posts: n/a
Default Re: SIGHUP and Session leaders (was Re: Start scripts under linux)

Peter T. Breuer wrote:
> I'll add that a little playing with ps -o pid,ppid,pgid,sid tells me
> that
>
> 1) the session leader is the shell run BY an xterm


Hmmm.. I think maybe so.

But it's not attached to a tty in this case anyway, so that couldn't be the
source. Let me check: Yes, the xterm sends the SIGHUP to the shell (used
strace to monitor) when it dies. But it doesn't send it to any of the
other processes. Doing a quick test, invoking a new bash, invoking a bg
process, exiting shell, the process lives. Sending a SIGHUP causes the
shell to SIGHUP the bg process. This doesn't really change anything below,
though, it's just filling in a hole.

> 2) the xterm belongs to the same session as the shell it is run FROM.


Yes.

> Ditto process group, as far as I can see.


....not on my computer? Don't know why. (Doesn't matter.)

> So when you fork a process (i.e. in background) from a foreground
> process in a shell within an xterm, it should have the process group and
> the session group of the shell, which the shell leads.
>
> When its parent dies and control returns to the shell (prompt), then the
> surviving process is inherited by init and its parent changes to 1,
> while its process group remains that of the (dead) parent that launched
> it. Its session group remains that of the shell.


I think so too. yes.

>
> Its session leader has not died and so it should not and does not get
> HUP at that point.
>
> If now you kill the xterm (or the shell), then the shell dies and
>
> A) IF it is set to send sighup to children does so
> (which does not include the process inherited by init!)



> B) sighup is sent to the process group of the shell
> (which doesn't include the process you forked).



Sounds good to me.

> So I don't see how one should ever expect that such a process would die.
>
> Usually anyway when forking a daemon process one takes pains to set its
> process group away from what it was so that it won't be associated with
> the tty it was launched from, and won't receive signals from it and
> won't block on input or output from/to it.
>
>
> Peter


Nice! It makes sense and everything. I have to muse on it a little more, but
that sounds logical to me.

Jon.
-- * Does the walker choose the path, or does the path choose the walker?
(fr. Sabriel) * --
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 08:01 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com