PDA

View Full Version : why wrong file descriptor ??


alokdotnet
08-13-2006, 01:51 AM
1 //redirecting output of ls -l command to wc, with help of tmp file
2
3 #include<stdio.h>
4 #include<fcntl.h>
5
6
7 void main()
8 {
9 int fd ;
10 switch(fork())
11 {
12 default : break ;
13
14 case -1 : fprintf(stderr, "system error\n") ;
15 exit(1) ;
16 case 0 : if((fd = open("tmp", O_CREAT|O_WRONLY,0600\
17 )) == -1)
18 {
19 perror("open") ;
20 printf("Couldn't create tmp file\n") ;
21 exit(2) ;
22 }
23
24 close(1) ; // closing 1 row
25 if(dup(fd) != 1)
26 {
27 fprintf(stderr, " Dup error...");
28 exit(3) ;
29
30 }
31 close(fd) ; // closing the extra file des
32 execl("/bin/ls","ls","-l", NULL) ;
33 fprintf(stderr,"error exit 4") ;
34 } // end of switch
35
36 switch(fork()) // this fork for wc
37 {
38 case -1 : // if not able to fork
39 break;
40 case 0 :if((fd = open("tmp", O_CREAT|O_WRONLY,0600\
41 )) == -1)
42 {
43 perror("open") ;
44 printf("Couldn't create tmp file\n") ;
45 exit(2) ;
46 }
47
48 close(0); // freeing the 0th row in file table
49
50 //printf("fd = %d\n", dup(fd)) ;
51 //close(0) ;
52 if(dup(fd) != 0)
53 {
54 fprintf(stderr," wc input error(dup)");
55 exit(4) ;
56 }
57
58 // close(fd) ;
59 execl("/usr/bin/wc", "wc",NULL) ;
60 fprintf(stderr, "error wc exit 5");
61 exit(5) ;
62 }// end of wc switch
63
64
65
66 wait(NULL) ;
67 exit(0) ;
68 }// end of main


why wc ( word count) is telling wrong file descriptor????
cant we set stdin to wc....

RobSeace
08-13-2006, 05:51 PM
Um, you're opening the file for write-only and then trying to set it as stdin (FD 0)...
That's not going to work... You can't read from a write-only opened file...

But, the whole concept is flawed, anyway... Depending on scheduling behavior and
such things, when you open the file for reading (assuming you changed the code to
open it correctly, anyway) for the "wc", the "ls -l" may not have finished (or even
started yet!), so the resulting output may not be correct... If you insist on using a
temp file like that, you'll need to add some delay between the "ls -l" and "wc", to give
the former time to finish... The proper method would be to wait for the "ls -l" child to
die (setup a SIGCHLD handler) before starting the "wc" child...

However, the ideal way to handle a situation like this is to just use a pipe, rather than
a temp file at all... Just call pipe(), then give the write end of it to the "ls -l" child's
stdout, and the read end of it to the "wc" child's stdin, and you can then let them both
run at once, and everything will behave properly... This is how your shell would
implement such a thing, if you were to do "ls -l | wc"...