C open returns fd 0 after fork

Reading and writing to a socket and pipes works ok. When trying to open a file in a child process, the open returns a descriptor 0 and reading from it does not result any characters.

After forking two times:

Code:
  if( (pid = fork()) < 0){
    fprintf( stderr, "\nCan't fork, %i, errno %i '%s'.", err, errno, strerror(errno) );
  }else if (pid != 0){   /* parent */
    exit( 0 );
  }

Setting as session leader.

Code:
  setsid();

  if( (pid = fork()) < 0 ){
    fprintf( stderr, "\nCan't fork (2), %i, errno %i '%s'.", err, errno, strerror(errno) );
  }else if( pid != 0 ){ /* parent */
     exit( 0 );
  }

setting the work directory to '/' and umask.

Code:
err = chdir( &(rootdir[0]) );
err = umask( (mode_t) 0x00 | S_IXUSR | S_IXGRP | S_IRWXO ); // mask 117

After a connection to socket, fork and duplicate the fd.

Code:
pid = fork();
if( pid==0 ){
  *pdupcsocket = dup( *pcsocket );
  err = chdir( <dirpath of program root> );
  ...
}

After some piping and setting three processes to communicate with the pipes, a file name is appended to the dirpath array and opened:

Code:
*fd = open( &(*dirpath)[0], flags ); // flags (O_RDONLY|0x00)

Verifying the filename. Filename printed is a real file, readable and the string is null terminated:

Code:
for( err=0; err<=(dirlen+fnamelen) ; ++err )
    fprintf( stderr, "[%c, 0x%.2x]", (unsigned char) (*dirpath)[err],  (unsigned int) (*dirpath)[err] );
fprintf( stderr, " length %i, last, no. %i: [%c, 0x%.2x].", err, err, (unsigned char) (*dirpath)[err], (unsigned int) (*dirpath)[err];

And after this, the open returns the *fp 0 and reading from it does not give any characters from the file.

Why the file is not open? Open returns 0 (err=0) and the *fp is 0. This is not an error because 0 is not <0. (The last errno from the previous error was 9 not from here.)

I have once fixed an error where the process wanted to read from the console. I don't remember the solution. Was it that the dup was needed? What is the reason here? The file to be opened is a new file. Why the process can't open the file?

/escape
 
Before too much trouble from anyone.

After testing the open in loop several times, the next open returned a new fd number from the end of the range of the used fd numbers and not from the beginning. Second test, reading something from the file showed that the file was after all readable. The characters could be printed to an output. Everything in this post is now ok. The problem is somewhere I should have already tested :( and not in something in this post.

stdin must be just free to use in the child process? It does not have an input and the number 0 is reallocated? This was so similar "bug" as the previous ones and because of this, misleading.

/escape
 
Sorry, but the whole post seems like you are thinking out loud .....

However, here is my 2 cents
stdin must be just free to use in the child process?
Yes, if you main() can use stdin (and it should), child process should be able to use it as well.

From fork(2)
Code:
The child process has its own copy of the parent's descriptors.
  These descriptors reference the same underlying objects, so
  that, for instance, file pointers in file objects are shared
  between the child and the parent, so that an lseek(2) on a
  descriptor in the child process can affect a subsequent read(2)
  or write(2) by the parent.  This descriptor copying is also
  used by the shell to establish standard input and output for
  newly created processes as well as to set up pipes.
 
Yes. If stdin (fd 0) is closed in the parent, it is reused in the child process after pipe(2) command. The pipe can use the 0 as well.
 
Back
Top