A
Alexander N. Spitzer
I am trying to write a program that will fork a process, and execute the
given task... the catch is that if it runs too long, I want to clean it up.
this seemed pretty straight forward with a single executable being run
from the fork. The problem I am having now is that if I call a shell
scripts, then lets say calls "xterm &", after the timeout has occurred,
I kill the shell script, but the xterm is still running... I cannot seem
to kill the "xterm" without giving a vicious enough kill that ends up
terminating everything including the original parent process...
anyone know how to send a kill forcibly signal to a forked pid, and ITS
PGPID (while not having the parent get hit with the signal?)
--------------------------CUT--------------------------
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
extern int errno;
int main(int argc, char** argv)
{
pid_t pid; /* PID of child */
pid_t retval;
int status; /* exit status from child, returned by wait */
long timer=0;
int count=0;
pid_t pgpid;
if (argc < 3)
{
printf("223 syntax: %s [timeout] [command] {params}\n",argv[0]);
exit(223);
}
timer=strtol(argv[1], (char **)NULL, 10);
if (timer == 0)
{
fprintf(stderr, "224 invalid time: %i\n",timer);
exit(224);
}
switch (pid = fork())
{
case 0:
/* child process */
/* printf("trying to execute: %s\n",argv[2]); */
if (argc > 3)
{
int i=0;
for(i=3;argv !=NULL;i++)
printf("arg %i: %s\n",i,argv);
execv(argv[2],&argv[2]);
}
else
{
/******************
okay, what is going on here?!?!?
in linux, I can just put "NULL" as the second
param in execv, but when running on solaris,
it causes a segfault... so this way seems to
work for both linux and solaris....
*******************/
char *nully_furtado=NULL;
execv(argv[2],&nully_furtado);
}
fprintf(stderr, "221 exec failed (%i)\n",errno);
exit(221);
break;
case -1:
/* fork has failed, so do nothing */
fprintf(stderr, "222 fork failed\n");
exit(222);
break;
default:
timer=timer * 10000;
do
{
/* printf("PID: %i\n",pid); */
retval = waitpid(pid,&status,WNOHANG);
usleep(250);
count=count+250;
if (count > timer)
{
pgpid=getpgid(retval);
/* printf("pgpid: %i\n",pgpid); */
fprintf(stderr, "220 too long\n");
kill((-1 * pgpid),9); /* kill everyone in the group */
exit(220);
}
}
while (retval != pid);
fprintf(stderr, "%i status\n",status);
exit(status);
break;
}
return 0;
}
given task... the catch is that if it runs too long, I want to clean it up.
this seemed pretty straight forward with a single executable being run
from the fork. The problem I am having now is that if I call a shell
scripts, then lets say calls "xterm &", after the timeout has occurred,
I kill the shell script, but the xterm is still running... I cannot seem
to kill the "xterm" without giving a vicious enough kill that ends up
terminating everything including the original parent process...
anyone know how to send a kill forcibly signal to a forked pid, and ITS
PGPID (while not having the parent get hit with the signal?)
--------------------------CUT--------------------------
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
extern int errno;
int main(int argc, char** argv)
{
pid_t pid; /* PID of child */
pid_t retval;
int status; /* exit status from child, returned by wait */
long timer=0;
int count=0;
pid_t pgpid;
if (argc < 3)
{
printf("223 syntax: %s [timeout] [command] {params}\n",argv[0]);
exit(223);
}
timer=strtol(argv[1], (char **)NULL, 10);
if (timer == 0)
{
fprintf(stderr, "224 invalid time: %i\n",timer);
exit(224);
}
switch (pid = fork())
{
case 0:
/* child process */
/* printf("trying to execute: %s\n",argv[2]); */
if (argc > 3)
{
int i=0;
for(i=3;argv !=NULL;i++)
printf("arg %i: %s\n",i,argv);
execv(argv[2],&argv[2]);
}
else
{
/******************
okay, what is going on here?!?!?
in linux, I can just put "NULL" as the second
param in execv, but when running on solaris,
it causes a segfault... so this way seems to
work for both linux and solaris....
*******************/
char *nully_furtado=NULL;
execv(argv[2],&nully_furtado);
}
fprintf(stderr, "221 exec failed (%i)\n",errno);
exit(221);
break;
case -1:
/* fork has failed, so do nothing */
fprintf(stderr, "222 fork failed\n");
exit(222);
break;
default:
timer=timer * 10000;
do
{
/* printf("PID: %i\n",pid); */
retval = waitpid(pid,&status,WNOHANG);
usleep(250);
count=count+250;
if (count > timer)
{
pgpid=getpgid(retval);
/* printf("pgpid: %i\n",pgpid); */
fprintf(stderr, "220 too long\n");
kill((-1 * pgpid),9); /* kill everyone in the group */
exit(220);
}
}
while (retval != pid);
fprintf(stderr, "%i status\n",status);
exit(status);
break;
}
return 0;
}