简体   繁体   中英

fgets doesn't return NULL in C

The loop was supposed to break but it keeps stuck on the fgets . process_P1 talks to inputHandler through a pipe. The problem is that inputHandler doesn't realize when process_P1 stops writing...the 'lalala' printf is never reached.

void process_P1(char *argv[], int fd[2], pid_t child)
{
    int bytes = 0;

    static char bufferIn[BUFFER_SIZE];
    static char bufferOut[BUFFER_SIZE];

    char line[BUFFER_SIZE];

    // close reading end of pipe
    close(fd[0]);

    FILE *in = fopen(getInput(argv), "r");
    FILE *out = fdopen(fd[1], "w");

    if (in == NULL) {
            sys_err("fopen(r) error (P1)");
    }
    int ret = setvbuf(in, bufferIn, _IOLBF, BUFFER_SIZE);
    if (ret != 0) {
            sys_err("setvbuf error (P1)");
    }

    if (out == NULL) {
            sys_err("fdopen(w) error (P1)");
    }
    ret = setvbuf(out, bufferOut, _IOLBF, BUFFER_SIZE);
    if (ret != 0) {
            sys_err("setvbuf error (P1)");
    }

    while (fgets(line, BUFFER_SIZE, in) != NULL)
    {
            fprintf(out, "%s", line);
            bytes += count(line) * sizeof(char);
    }

    // alert P2 to stop reading
    //fprintf(out, "%s", STOP);

    fclose(in);
    fflush(out);
    fclose(out);

    printf("P1: file %s, bytes %d\n", getInput(argv), bytes);

    // wait P2 ends
    if (waitpid(child, NULL, 0) < 0) {
            sys_err("waitpid error (P1)");
    }
}

void *inputHandler(void *args)
{
    int ret;

    static char bufferIn[BUFFER_SIZE];
    char line[BUFFER_SIZE];
    struct node *iterator;

    int *fd = (int*)args;

    close(fd[1]);

    FILE *in = fdopen(fd[0], "r");
    if (in == NULL) {
            sys_err("fdopen(r) error (P2)");
    }
    ret = setvbuf(in, bufferIn, _IOLBF, BUFFER_SIZE);
    if (ret != 0) {
            sys_err("setvbuf(in) erro (P2)");
    }

    while (fgets(line, BUFFER_SIZE, in) != NULL)
    {
    //      printf("%s", line);
            iterator = firstArg;
            while (iterator->next != NULL)
            {
                    ret = sem_wait(&(iterator->sem));
                    if (ret == 0) {
                            strcat(iterator->buffer, line);
                    } else {
                            sys_err("sem_wait error");
                    }
                    ret = sem_post(&(iterator->sem));
                    if (ret != 0) {
                            sys_err("sem_post error");
                    }
                    iterator = iterator->next;
            }
            line[0] = '\0';
    }
    printf("lalala\n");
    iterator = firstArg;
    while (iterator->next != NULL)
    {
            ret = sem_wait(&(iterator->sem));
            if (ret != 0) {
                    sys_err("sem_wait error");
            }
            iterator->shouldStop = 1;
            ret = sem_post(&(iterator->sem));
            if (ret != 0) {
                    sys_err("sem_post error");
            }
            iterator = iterator->next;
    }

    fclose(in);

    return NULL;
}

The problem is probably not in the code you show. Since you mention a pipe, your problem is probably in the plumbing related to that — and most likely, you did a dup2() on one end of the pipe to make it into standard input or standard output, but you forgot to close the file descriptor that you duplicated, or you forgot to close the other end. The fgets() won't terminate until there's no process that could write to the pipe that it is reading from. If the process that is reading still has the write end of the pipe open, it will stay stuck in the read, waiting for it to write something.

So, look hard at your piping code. Make sure you've closed both the values returned by pipe() after you've duplicated one end to standard input or standard output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM