From: arashamiri on
hi!
i have a shell script "A" which forks a background process "B" which
again forks a background process "C".

is there a way to pause my script "A" and continue ONLY after "C" is
done?

greetings, arash.

or another approach:
- i want to stop my tomcat using a script
- catalina.sh seems to fork another process to stop the server
- is there a way to find out if tomcat has stopped?
(this one probably does not fit into this group)

greetings, arash.

From: Sine Nomine on
On 10/21/2005 11:22 AM, arashamiri(a)hotmail.com wrote:
> hi!
> i have a shell script "A" which forks a background process "B" which
> again forks a background process "C".
>
> is there a way to pause my script "A" and continue ONLY after "C" is
> done?

At the quick & easy end of the robustness scale: man pgrep
From: Enrique Perez-Terron on
On Fri, 21 Oct 2005 12:22:55 +0200, <arashamiri(a)hotmail.com> wrote:

> hi!
> i have a shell script "A" which forks a background process "B" which
> again forks a background process "C".
>
> is there a way to pause my script "A" and continue ONLY after "C" is
> done?

This is not immediately easy. If you can modify B or C, you can make C
send a signal to A just before a C terminates, or you can make B detect
when C terminates and emit a signal to A.

If you cannot change B or C in any way, you need to have some knowledge
about C, that A can use to determine when C has terminated. One such
piece of knowledge is what executable program C is running, and, assuming
no other process is running the same executable, your A program can find
the process ID of the process using that executable, and then wake up
regularly to check if the process is still running.

Another piece of knowledge would be if the process C locks a file,
and you could let A do a blocking call to the suitable locking
function for the same file. Then the locking function will put
A to sleep and wake up when the C's lock on the file is removed.

> or another approach:
> - i want to stop my tomcat using a script
> - catalina.sh seems to fork another process to stop the server
> - is there a way to find out if tomcat has stopped?

This sounds like a somewhat different scenario. But take my words
with a suitable grain of salt, because I don't know what tomcat is,
and I may be talking nonsense.

What this sounds like to me, is that some program X (e.g., /sbin/init)
starts a program Y (tomcat), and then there is a fairly unrelated
program A (your script) that starts another script B (catalina.sh)
which "seems to fork another process" C "to stop the server" Y.

How to discover from A that C has finished... but that does not guarantee
that Y has finished. C could just send a signal to Y and terminate, while
Y, upon receipt of the signal starts saving state information and other
cleanup operations before it terminates.

What you want in A is to detect when Y has terminated. If Y is a single
process, and you have found the process id, say TOMCAT_PID=$(...), then:

while [ -d /proc/$TOMCAT_PID ]
do
sleep $POLL_SECONDS
done

if you are running on a system with /proc filesystem.

If you can control the startup of process Y (tomcat), you can
change that so it starts a program of yours instead:

#include <fnctl.h>
#include <sys/file.h>

int main(int argc, char *argv[], char *env[])
{
int fd = open("/var/run/my-tomcat-lock", O_CREAT|O_RDWR, 0600);
int lk_result = flock(fd, LOCK_EX);
int pid = fork();

if (pid == 0) {
argv[0] = "/sbin/tomcat" /* or whatever */
execve(argv[0], argv, env);
_exit(255);
}
else if (pid >= 0) {
int status;
wait( &status ); /* hang until the server terminates */
flock(fd, LOCK_UN);
}
return 0;
}

(Untested. Add error handling as you like)

Then your A program can try to do

int fd = open("/var/run/my-tomcat-lock", O_RDONLY);
int lk_result = flock(fd, LOCK_SH);
flock(fd, LOCK_UN);
_exit(0);

The second line here will hang until the program above does
flock(fd, LOCK_UN).

The point with doing it this way is to not do any active looping and
polling, and be notified immediately when tomcat terminates.

-Enrique