Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2014
    residenza
    Cantalupa (TO)
    Messaggi
    24

    [C] errore in read_line, fork_file

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

  2. #2
    Utente di HTML.it
    Registrato dal
    May 2014
    residenza
    Cantalupa (TO)
    Messaggi
    24
    Risolto, chiudete pure.

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Non seguiamo la pratica di chiudere le discussioni quando vengono risolte, piuttosto, sarebbe cosa buona e giusta indicare in che modo hai risolto, in modo che possa eventualmente tornare utile ad altri, nel caso avessero il tuo stesso problema.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2014
    residenza
    Cantalupa (TO)
    Messaggi
    24
    Certamente, posto subito il programma corretto!
    Il problema principale era nella maschera di bit della open(), gli altri sono raffinamenti. Se qualcuno avesse consigli e/o miglioramenti lo ascolto con piacere!

    main.c
    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[31];
        int num;
        do {
            printf("Write the file name [Max 30 characters]\n");
            num = read_line(0, 31, 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 | O_TRUNC, 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[21];
                int n;
                do {
                    printf("Write no more then 20 characters\n");
                    n = read_line(0, 21, 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;  
            }
        }
        int cl;
        do {
            cl = close(fd);
            if(cl<0 && errno!=EINTR) {
                printf("Impossible close the file opened: ");
                break;
            }       
        }while(cl<0);
        
        exit(EXIT_SUCCESS);
    }
    read_line.c
    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);
    }

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2014
    residenza
    Cantalupa (TO)
    Messaggi
    24
    Ho una domanda sull'include: ho provato a creare una nuova cartella in cui ho messo i file read_line.c e read_line.h. Successivamente al posto di include "read_line.h" ho messo il percorso relativo include "..\read_line\read_line.h".
    Non capisco come mai mi dia errore. Uso NetBeans e ho creato il progetto come una libreria statica, forse dovevo crearla come applicazione C? Se provo ad usare il metodo il compilatore mi segnala questo errore:

    "/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
    make[1]: Entering directory '/cygdrive/c/Users/M68/Documents/NetBeansProjects/fork_operazioni'
    "/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/Cygwin_4.x-Windows/fork_operazioni.exe
    make[2]: Entering directory '/cygdrive/c/Users/M68/Documents/NetBeansProjects/fork_operazioni'
    cygwin warning:
    MS-DOS style path detected: ..\read_line\read_line.h
    Preferred POSIX equivalent is: ../read_line/read_line.h
    CYGWIN environment variable option "nodosfilewarning" turns off this warning.
    Consult the user's guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/usin...sing-pathnames
    mkdir -p build/Debug/Cygwin_4.x-Windows
    rm -f "build/Debug/Cygwin_4.x-Windows/main.o.d"
    gcc -c -g -MMD -MP -MF "build/Debug/Cygwin_4.x-Windows/main.o.d" -o build/Debug/Cygwin_4.x-Windows/main.o main.c
    main.c: In function 'main':
    main.c:24:5: warning: passing argument 3 of 'read_line' from incompatible pointer type [enabled by default]
    int r = read_line(0, 21, buffer);
    ^
    In file included from main.c:16:0:
    ..\read_line\read_line.h:15:5: note: expected 'char *' but argument is of type 'char **'
    int read_line(int fd, int buffer_size, char* buffer);
    ^
    main.c:29:5: warning: passing argument 1 of 'open' from incompatible pointer type [enabled by default]
    int fd = open(buffer, O_RDONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IXUSR);
    ^
    In file included from /usr/include/sys/fcntl.h:3:0,
    from /usr/include/fcntl.h:14,
    from main.c:14:
    /usr/include/sys/_default_fcntl.h:190:12: note: expected 'const char *' but argument is of type 'char **'
    extern int open _PARAMS ((const char *, int, ...));
    ^
    mkdir -p dist/Debug/Cygwin_4.x-Windows
    gcc -o dist/Debug/Cygwin_4.x-Windows/fork_operazioni build/Debug/Cygwin_4.x-Windows/main.o
    build/Debug/Cygwin_4.x-Windows/main.o: In function `main':
    /cygdrive/c/Users/M68/Documents/NetBeansProjects/fork_operazioni/main.c:24: undefined reference to `read_line'
    /cygdrive/c/Users/M68/Documents/NetBeansProjects/fork_operazioni/main.c:24.text+0x31): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `read_line'
    collect2: error: ld returned 1 exit status
    nbproject/Makefile-Debug.mk:62: recipe for target 'dist/Debug/Cygwin_4.x-Windows/fork_operazioni.exe' failed
    make[2]: *** [dist/Debug/Cygwin_4.x-Windows/fork_operazioni.exe] Error 1
    make[2]: Leaving directory '/cygdrive/c/Users/M68/Documents/NetBeansProjects/fork_operazioni'
    nbproject/Makefile-Debug.mk:59: recipe for target '.build-conf' failed
    make[1]: *** [.build-conf] Error 2
    make[1]: Leaving directory '/cygdrive/c/Users/M68/Documents/NetBeansProjects/fork_operazioni'
    nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
    make: *** [.build-impl] Error 2


    BUILD FAILED (exit value 2, total time: 950ms)

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.