This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

My shutdown script - it works!


I tried that shutdown script written by Chuck Messenger.  It did not
work well on my Win98 system.  It hung the window and then I had trouble
getting to shutdown the rest of the way because a had no working
interactive window.

My scheme really works by killing off process group leaders.  The
calling process group leader is killed last.  One note.... in EVERY rxvt
window I start, I always put it into it's own process group.  Source
code to setpgrp.c is attached if interested.

Basically a gawk script reads the ps(1) output and generates a shell
script.  When the generated script is executed, all CYGWIN processes are
effectivly killed.  It is fast too!

Here is my short shutdown script:

#!/bin/bash
#
#	Shutdown the cygwin system
#
#	First we send SIGKILL to all process NOT in our process
#	group.  Then after a 10-second sleep, we send SIGKILL.
#
#	The last step is to kill off our process group.
#
#	Written: Paul E. McFerrin  02/15/02

ME=`basename $0`
TMP=/tmp/${ME}_tmp # generated script name
>$TMP
if [ -z "$CONSOLE_TTY" ]
then
	echo "You must execute $ME in the console (first) window!!"
	exit 2
fi
echo -e "\nShutting down CYGWIN ..."
AWKPGM='
#     PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
#  442949       1  442949 4294461843    0  500 02:35:28 /usr/bin/KSH
#  652513       1  652513 4294323867    0  500 02:35:43 /usr/bin/RXVT
/PID/ { next }
{
	if( $1 == pid ) {
		ourpgrp = $3
	}
	pgroup[$3 ""] = $3
	next
}
END {
	print "exec 2>/dev/null" >TMP # do not want error messages from kill
	print "# Our process group = " ourpgrp >>TMP
	for( g in pgroup ) {
		if( g != ourpgrp ) {
			print "echo + kill -15 -" g >>TMP
			print "kill -15 -" g >>TMP
		}
	}
	print "sleep 10" >>TMP
	for( g in pgroup ) {
		if( g != ourpgrp ) {
			print "echo + kill -9 -" g >>TMP
			print "kill -9 -" g >>TMP
		}
	}
	print "# killing off our process group" >>TMP
	for( g in pgroup ) {
		if( g == ourpgrp ) {
			print "echo + kill -9 -" g >>TMP
			print "kill -9 -" g >>TMP
		}
	}
}'
ps -a | gawk "$AWKPGM" TMP=$TMP pid=$$
if [ -s $TMP ]
then
	trap '' 1 15 # shields up!
	/bin/sh $TMP
fi
# in theory, the exit should not be reached as we should have just been
killed
exit 0
#################################################################

The above script must be executed in only the first (console) window. 
Below is a fragment of .bash_login file that defines the console tty (it
is not always /dev/conin) :

export ENV=/dev/null
export CYGWIN=tty
if [ $PPID == "1" ]
then
	 echo -e "\nStarting rxvt ... PID=$$ PPID=$PPID\n" && sh $bin/startx
	node=`uname -n`
	if [ "$node" = "OH0012-PEM" ] # don't want clients running services
	then
		echo -e "\nStarting services ...\n"
		/usr/local/apache/bin/apachectl restart
	fi
	export CONSOLE_TTY=`tty` # define this window as the console window
	#;;
fi

############################################################3

The important items to note is the checking if PPID == 1 & setting
CONSOLE_TTY.  This identifies the console (first) window.  To startup
any rxvt windows, I always call script "startx".  It is listed here:

#!/bin/sh
set -x
ENV=$HOME/.bash_login
export ENV
# start 'rxvt' in it's own process group !
setpgrp rxvt -rv -tn ansi -sl 1500 -fn 'Lucida Console-12' -e ksh &
sleep 1
###################################################

Everything works like a charm for me.  One note, I use ksh so there
might be some tweeking with other shells (export VAR=value   replaced
with  VAR=value ; export VAR)

-paul mcferrin



-- 
NOTE***  This email looks it came from MailHole@insight.rr.com but in
          reality it came from pmcferrin@insight.rr.com.  If you send
          a reply to this message, it *should* get delivered to the
          correct place.
#ident	"@(#)setpgrp.c 1.0 06/14/00"
/*
	Execute commands specified as arguments in another process group.
	Usefull to disassociate from the current process group and/or
	tty.
*/

#include <stdio.h>

main( argc, argv )
int	argc;
char	*argv[];
{
	char	*cmd, **p;
	
	cmd = *argv;
	if( argc <= 1 ) {
		fprintf( stderr, "Usage:  %s command [ arg ... ]\n", cmd );
		exit(1);
	}
	argv++;
	argc--;
	setpgrp();
	execvp( *argv, argv );
	fprintf( stderr, "%s: %s execvp failed.  ", cmd, *argv );
	perror( "" );
	exit( 1 );
}

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]