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);
}