Below program neither load the program to child process nor prints "before" and "after". However ps aux shows the creation of processes (but without loading args0 program). I am using PIPE defined as socketpair. args0[] holds executable name for the child program, args1[] holds the name of the child program. args2 and args3 are predefined values that doesn't change and should be sent to the children as arguments. you can assume char args2[] = "10" --> user input (digit) and converted to string. I just do not understand why at least printf("before") is not printed. i read about fflush and putting \n at every printf, and i did. so everything in my program is printed correctly up to this point.
I would truly appreciate your responses.
char args2[];
char args3[];
//creating pipe
int forkk(pipes *myPipe, server_message *m, char args0[],char args1[]) {
pid_t cpid;
//pipe passed myPipe[i]
if (PIPE(myPipe->fd) == -1) {
perror("pipe error\n");
return -1;
}
fork();
cpid=getpid();
if (cpid == -1) {
perror("fork error\n");
return -1;
}
if (cpid) {
close(myPipe->fd[1]);
return 1;//closing one end of parent
} else {
for (int i = 3; i <= myPipe->fd[0]; i++) {
close(i);
}
dup2(myPipe->fd[1], 0); //redirecting stdin of child
dup2(myPipe->fd[1], 1); //redirecting stdout of child
close(myPipe->fd[1]);
myPipe->cpid = cpid;
char *newargs[3];
newargs[0]=args1;
newargs[1]=args2;
newargs[2]=args3;
printf("before\n");
//fflush(stdout);
execv(args0,newargs);
printf("after execv\n");
write(myPipe->fd[0], &m, sizeof(server_message)); //send the server_msg immediately (pass an array or msg)
}
return 2;
}
void main(){
....
scanf("%d %d", &width, &height);
sprintf(args2,"%d",height); //converting into to string
sprintf(args3,"%d",width);
char *args0 = "./prey";
char *args1 = "prey";
int r= forkk(&myPipes[2], &msg, args0,args1);
}
I cannot post the entire code as it is long and need explanation. I am most probably having a problem with pointer assignment that i wrongly think is the correct way. Thanks a lot for any kind of help
(spoiler: your
else
branch in your poorly namedforkk
is never taken!)Read carefully documentation of execv(3). You should provide a
NULL
terminated array.So you should at least code:
BTW, the first argument should generally be the program name. So you really want:
And the documentation also says
So in most cases, there is no point to continue here since
execv
won't return if successful. However, you need to catch the failure. I recommend after yourexecv
Your
write(myPipe->fd[0], &m, sizeof(server_message));
smells very bad. I see no point in doing that (only) whenexecv
failsBTW with strace(1) you would probably have caught such an error (missing terminating
NULL
pointer forexecv
).At last, you always should keep the result of fork(2). See this. So replace:
with
cpid = fork();
Of course, you need to handle the three cases:
cpid== -1
(which you forgot to handle!),cpid== 0
,cpid> 0
.Again, read carefully getpid(2):
and (about
getpid
&getppid
):So
getpid
never returns 0 (and that is why yourelse
branch in yourforkk
poorly named function, containing theexecvp
, never runs). See also credentials(7).Your
void main()
is also wrong.main
should return anint
. You generally define it asint main(int argc, char**argv)
...PS. Take the habit of reading carefully the documentation of every function you are using.
Your
forkk
is very poorly named, too similar to the very importantfork
name.