I have the following function which execute command via fork and execvp. my script that I launch in fork is listening for input data. How I can send data to myscript?
int external_command()
{
int pfds[2];
if (pipe(pfds) < 0)
return -1;
if ((uproc.pid = fork()) == -1)
return -1;
if (uproc.pid == 0) {
/* child */
const char *argv[4];
int i = 0;
argv[i++] = "/bin/sh";
argv[i++] = "myscript.sh";
argv[i++] = NULL;
close(pfds[0]);
dup2(pfds[1], 1);
close(pfds[1]);
execvp(argv[0], (char **) argv);
exit(ESRCH);
} else if (uproc.pid < 0)
return -1;
/* parent */
close(pfds[1]);
int status;
while (wait(&status) != uproc.pid) {
DD("waiting for child to exit");
}
char buffer[64];
ssize_t rxed;
char *c;
int t;
//read from fork pipe
*value = NULL;
while ((rxed = read(pfds[0], buffer, sizeof(buffer))) > 0) {
if (*value)
t = asprintf(&c, "%s%.*s", *value, (int) rxed, buffer);
else
t = asprintf(&c, "%.*s", (int) rxed, buffer);
if (t == -1) return -1;
free(*value);
*value = strdup(c);
free(c);
}
// how to write to the pipe fork?
}
A pipe is unidirectional. Call pipe
twice, to get one pair of file descriptors for reading data from the child (as you already have) and another to sent data to the child (which will be new). You'll need to do the same sort of dup2
and close
magic as you're already doing, in order to set up that new pipe as stdin for the child.
I guess you mean that you want to write to the child process stdin
from the parent process? For that you need to create two pipes. One that is used as stdout
in the child, like you have now, and the other have to be used for stdin
is much the same fashion as you do now (but with the indexes reversed of course).
Of course, you can't wait
for the child before you write to it, as then you might have a deadlock if the child needs input to continue.
basics of a pipe
please study this bit of code so you learn what you are doing
int fd[2]; /*write(fd[1],buffer,strlen)
/ read(fd[0],buffer2,SIZE)*/
pid_t cpid;
if(pipe(fd)==-1){
perror("pipe");
exit(EXIT_FAILURE);
}
if((cpid=fork())<0){/* FORK INIT */
printf("\n\tFORK ERROR\n");
exit(1);
}
if(cpid==0){ /*SON*/
close(fd[0]);
/********CODE******/
if((write(fd[1],final2,strlen(final2)))<0){
perror("\n\tWRITE ERROR");
}
close(fd[1]);
}else{ /*FATHER*/
close(fd[1]);
if((read(fd[0],aler,NN))<0){
perror("\n\tREAD ERROR");
}
wait(NULL);
/********CODE******/
close(fd[0]);
}
in this case the parent process(father) read() information from the new(son) process
if you want BI-directional read() write() create 2 pipes(fd1[2],fd2[2])
use the same logic as above, father reads, close the write end fd1[1], son writes, close the read end fd1[0]
vice-versa to the other direction
father writes, close the read end fd2[0], son reads, close the write end fd2[1]