12-15-07 06:21 PM
mathog@caltech.edu wrote:
> I'll have to do a few experiments
> to see which forms of exec() used to start the cassette image result
> in a running process which
> can actually use the parent's fd's.
It works just like advertised, even for execlp using the "sh"
mechanism. Here's a test case:
cat >/tmp/input1.txt <<EOD
1
2
3
EOD
wc /tmp/input1.txt
# emits this: 3 3 6 /tmp/input1.txt
cat >parent.c <<EOD
/*
build me with
gcc -Wall -std=c99 -o parent parent.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void insane(char *string){
(void) fprintf(stderr,"%s\n",string);
exit(EXIT_FAILURE);
}
int main(void){
int fd;
int child;
char cmdstring[1000];
fd=open("/tmp/input1.txt",'r');
if(!fd)insane("fatal error: open failed");
sprintf(cmdstring,"./child %d",fd);
(void) fprintf(stdout,"pre fork, command is %s\n",cmdstring);
child=fork();
if (child > 0) {
sleep(100000); /* parent has to do something or other */
}
else {
execlp("sh", "sh", "-c", cmdstring,NULL);
insane("fatal error: exec for cmd failed");
}
exit(EXIT_SUCCESS);
}
EOD
cat >child.c <<EOD
/*
build me with:
gcc -Wall -std=c99 -o child child.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv){
int fd;
int count;
char string[1000];
(void) fprintf(stdout,"in child arg1 %s\n",argv[1]);
count = sscanf(argv[1],"%d",&fd);
(void) fprintf(stdout,"in child fd %d\n",fd);
count = read(fd,string,100);
(void) fprintf(stdout,"in child read %d\n",count);
exit(EXIT_SUCCESS);
}
EOD
gcc -Wall -std=c99 -o parent parent.c
gcc -Wall -std=c99 -o child child.c
./parent
which emits this:
pre fork, command is ./child 3
in child arg1 3
in child fd 3
in child read 6
6, exactly as it should be for that input file.
That wasn't so hard after all.
Thanks all for the feedback,
David Mathog
[ Post a follow-up to this message ]
|