Home > Archive > Unix Programming > April 2005 > Newbe help with fork, pipe and execlp
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Newbe help with fork, pipe and execlp
|
|
|
| I have a task to do in school which im stuck in. The objective is to
make our own gcc driver which will pipe the three steps in compiling a
..c source file tougether. This is how it is suppose to be done:
..../cpp0 ... pself.c | .../cc1 ... | .../as ... --> creates pself.o
/collect2 ... ... --> creates pself.x
The requirements is that the program shall fork() childprocesses for
every step which will pipe its result so that the next step can start
their processing.
My problem is that when I'm running "execlp.. as.." ahe assambler
refuses to read from standard input (which really is from the pipe).
I´ve tested whith just reading from standard input with read, and it
works perfectly. Can someone please help me with this.. cause i´m
getting desperate!! here is my code:
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#define READ 0
#define WRITE 1
main(int argc, char *argv[])
{
int status, n, fd[2], fd2[2], test;
char line[4096];
if (pipe(fd) < 0 || pipe(fd2) < 0) {
perror("Can't create pipe \n");
exit(1);
}
switch ( fork() )
{
case 0: /* Son - Producer */
close(WRITE);
dup(fd[WRITE]);
close(fd[READ]);
execlp("/usr/lib/gcc-lib/i386-linux/2.95.4/cpp0",
"cpp0", "-lang-c", "-D__GNUC__=2", "-D__GNUC_MINOR__=95",
"-D__ELF__", "-Dunix", "-D__i386__", "-Dlinux", "-D__ELF__",
"-D__unix__", "-D__i386__", "-D__linux__", "-D__unix", "-D__linux",
"-Asystem(posix)", "-Acpu(i386)", "-Amachine(i386)", "-Di386",
"-D__i386", "-D__i386__", argv[1], NULL);
perror(" cannot execlp1");
exit(1);
case -1: /* FAIL */
perror(" Cannot fork \n");
exit(1);
}
/*(void) wait(&status);*/
switch ( fork() )
{
case 0: /* Consumer */
close(READ);
dup(fd[READ]);
close(fd[WRITE]);
close(WRITE);
dup(fd2[WRITE]);
close(fd2[READ]);
execlp("/usr/lib/gcc-lib/i386-linux/2.95.4/cc1",
"cc1", "-dumpbase", argv[1], "-version", "-o", "-", NULL);
perror(" cannot execlp2");
exit(1);
case -1: /* FAIL */
perror(" cannot fork \n");
exit(1);
}
/*(void) wait(&status);*/
switch ( fork() )
{
case 0:
close(READ);
dup(fd2[READ]);
close(fd2[WRITE]);
/* if ( (test = creat("newfile.s", 0644)) == -1 )
{
printf("Cannot create new File\n");
exit (1);
}
printf("BEFORE READ\n\n");
n = read(READ, line, 4096);
write(WRITE,line,test);
*/ printf("AFTER READ\n\n");
execlp("/usr/bin/as", "as", "-V", "-Qy", "-o",
"newfile.o", NULL);
perror(" cannot execlp3");
exit(1);
case -1:
perror(" cannot fork \n");
exit(1);
}
/* close(fd[READ]);
close(fd[WRITE]);
close(fd2[READ]);
close(fd2[WRITE]);
*/
(void) wait(&status);
/* (void) wait(&status);
(void) wait(&status);
*/ printf("\nAFTER WAIT\n");
execlp("/usr/lib/gcc-lib/i386-linux/2.95.4/collect2",
"collect2", "-m", "elf_i386", "-dynamic-linker", "/lib/ld-linux.so.2",
"/usr/lib/crt1.o", "/usr/lib/crti.o",
"/usr/lib/gcc-lib/i386-linux/2.95.4/crtbegin.o",
"-L/usr/lib/gcc-lib/i386-linux/2.95.4", "newfile.o", "-lgcc", "-lc",
"-lgcc", "/usr/lib/gcc-lib/i386-linux/2.95.4/crtend.o",
"/usr/lib/crtn.o", "-o", "newfile.x", NULL);
printf("\nAFTER LINKING\n");
exit(0);
}
| |
| Fletcher Glenn 2005-04-22, 8:57 pm |
| Johan wrote:
> I have a task to do in school which im stuck in. The objective is to
> make our own gcc driver which will pipe the three steps in compiling a
> .c source file tougether. This is how it is suppose to be done:
>
> .../cpp0 ... pself.c | .../cc1 ... | .../as ... --> creates pself.o
> /collect2 ... ... --> creates pself.x
>
> The requirements is that the program shall fork() childprocesses for
> every step which will pipe its result so that the next step can start
> their processing.
>
<code snipped>
I looked at the code, and it's apparent that you do not have
a clear understanding of a pipe chain. In order to have all
of the processes in the chain connected, you must fork the
first child, which connects the pipe to the parent. The
child must fork a grandchild which connects a pipe to its
parent. This continues to the end of the chain. The chain
of children then exec their processes which can proceed in
parallel.
--
Fletcher Glenn
| |
|
| Thanks for your help. I´ve solved it now, you was right it was some
unclosed pipes that caused the problem
|
|
|
|
|