[comp.unix.wizards] Checking for new mail

bmw@isgtec.UUCP (Bruce Walker) (08/29/89)

Since I haven't seen anyone mention it yet, I will:
in the extremely well-written and useful book "The UNIX Programming
Environment" by Kernighan and Pike, there is a small bit of C called
"checkmail" (pg. 216).  To link it you'll also need a code fragment
called "error()" (pg. 207).

This program does what none of the to-date posted ones do: it checks
for the mail file *growing*, not just *changing*; otherwise you'll
get "you have mail" messages after you read your mail (and it is
deleted from your mailbox).

Not mentioned in the book though, is the fact that this program will
not work as advertised on BSD systems.  You are supposed to start it
like this (usually from .login):

	$ checkmail&

which is fine under SysX, since when you log out, it goes away by
itself.  However, if you do this on a Sun (f'rinstance), the process
disconnects from your tty and continues running (inherited by root).
You end up with dozens of the little buggers.

My (slightly klugey) solution is to add a line to my .logout (csh):

	/bin/kill -9 `ps x | awk '$5=="checkmail" {print $1}'`&

Anyone know a better way?
-- 
Bruce Walker                          ...uunet!mnetor!lsuc!isgtec!bmw
"Better Living Through Connectivity"         ...utzoo!lsuc!isgtec!bmw
ISG Technologies Inc. 3030 Orlando Dr. Mississauga. Ont. Can. L4V 1S8

seth@ctr.columbia.edu (Seth Robertson) (08/30/89)

In article <128@isgtec.UUCP> bmw@isgtec.UUCP (Bruce Walker) writes:
>the process
>disconnects from your tty and continues running ...

>My (slightly klugey) solution is to add a line to my .logout (csh):

>	/bin/kill -9 `ps x | awk '$5=="checkmail" {print $1}'`&

>Anyone know a better way?


Sure,  Modify checkmail so that does the following:

	if (kill(ppid,0))
	  exit(1);

So every so often, it checks to see if its parent is around.  If
it isn't, it performs honorable suicide.

Actually, it is also a good idea for the program to make its real PPID
to be 1.  That way you won't accidently kill it && you won't see it
when you do things like `jobs` (You would do it by having the program
call itself && having the first copy kill itself off.  The second copy
then gets a new process group and its parent id gets reset to 1.)

-- 
                                        -Seth Robertson
                                         seth@ctr.columbia.edu

shap@bunker.UUCP (Joseph D. Shapiro) (08/30/89)

In article <128@isgtec.UUCP> bmw@isgtec.UUCP (Bruce Walker) writes:
>My (slightly klugey) solution is to add a line to my .logout (csh):
>
>	/bin/kill -9 `ps x | awk '$5=="checkmail" {print $1}'`&
>
>Anyone know a better way?

when initiating it in .login:

	checkmail&
	echo $child > ~/kill.$$

in .logout:

	kill -9 ` cat ~/kill.$$ `
-- 
__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__
Joe Shapiro					"My other car is a turbo...
ISC-Bunker Ramo     				 ...too."
{decvax,yale,philabs,oliveb}!bunker!shap

amos@taux01.UUCP (Amos Shapir) (08/30/89)

In article <128@isgtec.UUCP> bmw@isgtec.UUCP (Bruce Walker) writes:
>You end up with dozens of the little buggers.
>
>My (slightly klugey) solution is to add a line to my .logout (csh):
>
>	/bin/kill -9 `ps x | awk '$5=="checkmail" {print $1}'`&
>
>Anyone know a better way?

alias logout 'kill -1 0'

This works in most versions of csh.

-- 
	Amos Shapir		amos@taux01.nsc.com or amos@nsc.nsc.com
National Semiconductor (Israel) P.O.B. 3007, Herzlia 46104, Israel
Tel. +972 52 522261  TWX: 33691, fax: +972-52-558322
34 48 E / 32 10 N			(My other cpu is a NS32532)

jdarcy@multimax.UUCP (Jeff d'Arcy,OS Avenue,2627,) (08/30/89)

bmw@isgtec.UUCP (Bruce Walker):
> [description of mail check program not terminating on BSD ]
>
> You end up with dozens of the little buggers.
> 
> My (slightly klugey) solution is to add a line to my .logout (csh):
> 
> 	/bin/kill -9 `ps x | awk '$5=="checkmail" {print $1}'`&

What a happy coincidence!  After changing jobs and finding no such beast
available, I wrote a program that does just what you describe.  I solved
the exact same problem by adding code to the main loop that checks the
parent process ID against whatever it was when the program started.  If
the two don't match, the parent obviously went away.  In two weeks of 
constant use on several machines (UmaxV and Umax4.x) I have seen neither
premature terminations or excessive persistence.

Jeff d'Arcy		jdarcy@encore.com		(508) 460-0500 x2627
  I am solely responsible for my own opinions, and not at all for others'

jdarcy@multimax.UUCP (Jeff d'Arcy,OS Avenue,2627,) (08/30/89)

seth@ctr.columbia.edu (Seth Robertson):
> Sure,  Modify checkmail so that does the following:
> 
> 	if (kill(ppid,0))
> 	  exit(1);
> 
> So every so often, it checks to see if its parent is around.  If
> it isn't, it performs honorable suicide.

This is an approach I'd tried earlier (I used SIGCHLD, actually) and
it worked OK, but I wasn't comfortable with the possibility that the
parent might try to do something with the signal instead of dropping
it.  That's when I thought of comparing initial vs. current PPIDs.

Jeff d'Arcy		jdarcy@encore.com		(508) 460-0500 x2627
  I am solely responsible for my own opinions, and not at all for others'

corbet@mead.uucp (Jonathan Corbet) (09/02/89)

bmw@isgtec.UUCP (Bruce Walker):

>However, if you do this on a Sun (f'rinstance), the process
>disconnects from your tty and continues running (inherited by root).
>You end up with dozens of the little buggers.
>
>My (slightly klugey) solution is to add a line to my .logout (csh):
>
>	/bin/kill -9 `ps x | awk '$5=="checkmail" {print $1}'`&
>
>Anyone know a better way?

How about if you add a line like:

	signal (SIGHUP, SIG_DFL);

toward the beginning of your main program?  That will cause the program
to die when the parent process does...


Jonathan Corbet
National Center for Atmospheric Research, Field Observing Facility
corbet@stout.ucar.edu

cudcv@warwick.ac.uk (Rob McMahon) (09/02/89)

In article <4201@ncar.ucar.edu> corbet@mead.UCAR.EDU (Jonathan Corbet) writes:
>How about if you add a line like:
>
>	signal (SIGHUP, SIG_DFL);
>
>toward the beginning of your main program?  That will cause the program
>to die when the parent process does...

I've seen a couple of people say things like this now.  It's not that csh sets
its children to ignore SIGHUP, but rather that they never see it.  Csh, at
least on BSD systems with job control, puts each `job' into a process group of
it's own, so that it can manipulate them (stop them as a complete job, move
them into the foreground by setting the process group associated with the
terminal the same as the job, put them into the background by doing the
opposite).

Since only processes in the process group associated with the terminal see
keyboard generated signals, including SIGHUP, background processes never even
have the signals delivered to them.  So the only ways round this are to either
have the shell kill the job before it goes away (by putting something in
.logout), or by having the job check that its parent is still around
occasionally, by checking the value of ppid(), or by kill(orig_ppid, 0)'ing.

Rob
-- 
UUCP:   ...!mcvax!ukc!warwick!cudcv	PHONE:  +44 203 523037
JANET:  cudcv@uk.ac.warwick             ARPA:   cudcv@warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England