Salve,
ho scritto un programma in cui un padre e un figlio condividono un file aperto: il figlio modifica il file scrivendo una riga di testo letta da terminale ( con l'uso della read_line che ho scritto) e il padre, dopo avere atteso la terminazione del figlio, stampa a video il contenuto del file.

Ho due errori che non riesco a risolvere, il primo è che la sys call open() non mi crea il file se non esiste, il secondo è che dopo aver scritto un testo (il quale sarà il contenuto del file) mi ritorna un errore. Com'è possibile che mi dia errore se il fd 0 è lo stdin? Vi allego tutte le informazioni utili e vi ringrazio molto in anticipo.

Write the file name [Max 10 characters]
pippo.txt
Write no more then 20 characters
test
Error in execution of read_line: : Bad file descriptor
RUN FAILED (exit value 1, total time: 19s)

I sorgenti sono corposi, li provo a copiare nel messaggio, in caso diano problemi ditemelo e li metto in allegato.

codice:
/* 
 * File:   main.c
 * Author: M68
 *
 * Created on 12 dicembre 2014, 12.23
 */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include "read_line.h"
#include <errno.h>


int main() {
    char file_name[30];
    int num;
    do {
        printf("Write the file name [Max 10 characters]\n");
        num = read_line(0, 30, file_name);
        if(num<0) {
            perror("Error in execution of read_line: ");
            exit(EXIT_FAILURE);
        }
    }while(num == 0);
    pid_t childPid;
    int fd = open(file_name, O_RDWR || O_CREAT, S_IRUSR || S_IWUSR || S_IXUSR);
    if(fd<0) {
        perror("Error opening file: ");
        exit(EXIT_FAILURE);
    }
    
    childPid = fork();
    switch(childPid) {
        case -1:
            perror("Error: ");
            exit(EXIT_FAILURE);
            break;
        case 0: {
            char buffer[20];
            int n;
            do {
                printf("Write no more then 20 characters\n");
                n = read_line(0, 20, buffer);
                if(n<0) {
                    perror("Error in execution of read_line: ");
                    exit(EXIT_FAILURE);
                }
            }while(n == 0);
            int w;
            do{
                w = write(fd, &buffer, n);
                if(w<0 && errno!= EINTR) {
                    perror("Error in execution of sys call write: ");
                    exit(EXIT_FAILURE);
                }
            }while(w<0 && errno == EINTR);
            break;
        }
        default: {
            int x = wait(NULL);
            if(x<0 && errno!=ECHILD) {
                perror("Error in execution of sys call wait: ");
                exit(EXIT_FAILURE);
            }
            x = lseek(fd, 0, SEEK_SET);
            if(x<0) {
                perror("Error in execution of sys call lseek: ");
                exit(EXIT_FAILURE);
            }
            char buffer[20];
            int n;
            n = read_line(fd, 20, buffer);
            if(n<0) {
                perror("Error in execution of read_line: ");
                exit(EXIT_FAILURE);
            }
            printf("%s", &buffer);
            break;  
        }
    }
    exit(EXIT_SUCCESS);
}
codice:
#include <unistd.h>
#include <errno.h>
#include "read_line.h"
/* need:
 * file descriptor for input
 * size of buffer
 * buffer
 * 
 * return:
 * number of characters
 * -1 in case of error
 * 
 * if returns a number != from -1, buffer is holding a string
 */
int read_line(int fd, int buffer_size, char* buffer) { //read a line of text(until /n) from an input file
    
    //check for invalid arguments (size<2 it's invalid cuz min size must be char + /0)
    if(buffer_size<2 || fd<0 || buffer == NULL) { 
        errno= EINVAL;
        return -1;
    }
    
    char next_char;
    int index = 0;
    int r;
    
    do {
       r = read(fd,&next_char,1);
       
       switch(r) {
           case -1: 
               if(errno == EINTR)  //if system call have been interrupted
                   continue;
               else                //other kind of error
                   return -1;
               break;
           case 0:
               if(index==0)
                   return 0;
               else {
                   buffer[index]='\0';
                   return index;
               }
               break;
           default:
               if(next_char=='\n') {
                   buffer[index]='\0';
                   return index;
               }
               if(index>=buffer_size-1) {
                   errno = ENOMEM;
                   return -1;
               }   
               buffer[index]=next_char;
               index++;
               break;    
       } 
    }while(index<buffer_size);
}