Program run in child process doesn't loop
I have a specific question regarding the parent process reading the stdout from child. My problem is that when I run the program, the child program should execute a new program multiple times in a loop but it runs it only once and exits to the parent process. The child process is running a simple program that prints a message to stdout. Thanks in advance.
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
#include <time.h>
#include <sys/wait.h>
#define ssec 1
#define fsec 0
#define secBuf 5
#define decbase 10
#define fgbuf 60
volatile sig_atomic_t aborting = 0;
void chld_handler (int sig)
{
if(sig == SIGINT){
aborting++;
}
}
int rand_start(int low, int high){ int s; int r = 0; srand(time(NULL));
s = rand();
r = s % high + low;
return r;
}
void Usage(){
printf("Usage :schedule [-s] [-f] n"); exit(1);
}
int main(int argc, char *argv[]){
/getopt variablen/ int opt; int index;
int sflag = 0; int fflag = 0;
char *svalue; char *fvalue;
int sseconds = ssec; int fseconds = fsec;
char *reactor; char *emergency; char *logfile;
/**/ char *endptr; /Pipe and child/
int pipepc1[2]; int pipepc2[2];
int child1_fd; int child2_fd;
FILE *log; FILE *pipe_reader;
char *p;
char *buf; int waitFc; int status; /prgm/ int prg_r; int prg_e;
/termination/ int cnt = 0; int start_period; p = malloc(fgbuf * sizeof(char)); buf = malloc(fgbuf * sizeof(char));
(void)signal(SIGINT,chld_handler);
if(argc < 4){
Usage();
}else if(argc == 4){
reactor = argv[1];
emergency = argv[2];
logfile = argv[3];
}else if(argc > 4){
/*argumentenbehandlung*/
while((opt = getopt(argc,argv,":s:f:")) != -1){
printf("sflag %d fflag %d n",sflag,fflag);
printf("opt %c n", opt);
printf("optind %d n ",optind);
switch(opt){
case 's':
if(sflag == 0){
sflag++;
svalue = optarg;
}else{
fprintf(stderr,"Widerholung der option -sn");
Usage();
}
break;
case 'f':
if(fflag == 0){
fflag++;
fvalue = optarg;
}else {
fprintf(stderr,"Widerholung der option -fn");
Usage();
}
break;
case ':' :
fprintf(stderr,"Option -%c brauch ein argumentn",optopt);
Usage();
break;
case '?' :
fprintf(stderr,"Nicht bekannte option -%c n",optopt);
Usage();
break;
default :
assert(0);
}/*switch*/
}/*while getopt*/
for(index = optind; index < argc; index++){
if((argc - index) == 3){
reactor = argv[index];
}else if((argc - index) == 2){
emergency = argv[index];
}else if((argc - index) == 1){
logfile = argv[index];
}
}/*for schleife*/
/* */
if(sflag){
sseconds = (int)strtol(svalue,&endptr,decbase);
printf("%d ssecn", sseconds);
}
if(fflag){
fseconds = (int)strtol(fvalue,&endptr,decbase);
printf("%d fsecn", fseconds);
}
}
/pipeing/
if(pipe(pipepc1) == -1){
fprintf(stderr,"Fehler bei der Erzeugung der pipen");
exit(1);
}else {printf("Pipe createdn");}
/erzeuge child1/ child1_fd = fork();
if(child1_fd < 0){
fprintf(stderr,"Fehler beim asfuehren von forkn");
exit(0);
}
if(child1_fd == 0){ printf(" CHILD n"); /close pipe read/ if(close(pipepc1[0]) == -1){
fprintf(stderr,"Konnte nicht das Read-Ende vom pipepc1 schliessenn");
exit(1);
}
if(close(1) == -1){
fprintf(stderr,"Konnte nicht das Read-Ende vom pipepc1 schliessenn");
exit(1);
}
if(dup(pipepc1[1]) !=STDOUT_FILENO){
fprintf(stderr,"Das setzen des Read-Endes als stdout is Fehlgeschlagenn");
exit(1);
}
if(fseconds == 0){
start_period = sseconds;
}else start_period = rand_start(sseconds,(sseconds + fseconds));
for(cnt = 0; cnt < 5; cnt++){
sleep(start_period);
fflush(stdout);
prg_r = execl(reactor,"",NULL);
//printf("prg_r ist %d n", prg_r);
}
if(close(pipepc1[1]) == -1){
fprintf(stderr,"Das neue stdout konnte nich geschlossen werdenn");
exit(1);
}
}else{
printf("**PARENT**n");
log = fopen(logfile,"w");
/*schliesse pipe read*/
close(pipepc1[1]);
pipe_reader = fdopen(pipepc1[0],"r");
while((buf = fgets(p,fgbuf,pipe_reader)) != NULL){
printf("from Child : %s n",buf);
fflush(pipe_reader);
}
fclose(log);
waitFc= waitpid(child1_fd,&status,0);
if(waitFc == -1){
fprintf(stderr,"Das Warten ist fehlgeschlagenn");
exit(1);
}
printf("child is donen und waitFc = %dn und satus %d",waitFc,status);
fclose(pipe_reader);
close(pipepc1[1]);
}
printf("argc = %d n", argc); exit(0);
}
and the reactor program :
#include <stdio.h> #include <stdlib.h> #include <time.h>
int main(){
srand(time(NULL)); int i; int s;
s = rand() % 7; /*printf("%d n",s);*/ if(s != 6){ printf("OKn"); fflush(stdout); }else { printf("PRESSURE TOO HIGH - IMMEDIATE SHUTDOWN REQUIRED"); exit(EXIT_FAILURE);
}
}
Well... you use fork() call to create a child process then execl() to execute another program. The problem is execl() replaces current proces image (your child process) with the image of the command you are executing. So at the end of first pass of for() loop your program gets replaced by the executing command. When it finishes it's job, it just simply quits, terminating the child process.
I think what you need to do is to call popen() instead of execl(). This will cause command to get executed in a separate process, rather than replacing your current process. If you want, you can even start all the commands at once (calling popen() in a loop) and then use select()/epool() to read data from child processes as soon as it becomes available.
It will not loop inside the child process because you are doing exec which typically means that it overlays the child process and will exit. If you want to loop , you will have to spawn another child process from your loop in which you will typically do only exec, so as it iterates it will spawn a child process inside which you do exec it will overlay and exit. So what you need to do is the following:-
for(cnt = 0; cnt < 5; cnt++){
sleep(start_period);
fflush(stdout);
child2_fd = fork();
if (child2_fd == 0){
prg_r = execl(reactor,"",NULL);
}
}
链接地址: http://www.djcxy.com/p/72144.html
上一篇: 指向函数中的字符串
下一篇: 在子进程中运行的程序不会循环