Reading from a file descriptor in C

cfile-descriptor

(correct me if im wrong on my terms) So i need to read from a file descriptor, but the read method takes in a int for byte size to read that much OR i can use O_NONBLOCK, but i still have to setup up a buffer size of an unknown size. making it difficult. heres what i have so far

this is my method that handles all the polling and mkfifo. and N is already predefined in main

struct pollfd pfd[N];
int i;
for(i = 0; i < N; i++)
{
    char fileName[32];
    snprintf (fileName, sizeof(fileName), "%d_%di", pid, i);
    mkfifo(fileName, 0666);
    pfd[i].fd = open(fileName, O_RDONLY | O_NDELAY);
    pfd[i].events = POLLIN;
    pfd[i].revents = 0;

    snprintf (fileName, sizeof(fileName), "%d_%do", pid, i);
    mkfifo(fileName, 0666);
    i++;
    pfd[i].fd = open(fileName, O_WRONLY | O_NDELAY);
    pfd[i].events = POLLOUT;
    pfd[i].revents = 0;
    i--;
}
while(1)
{
    int len, n;
    n = poll(pfd, N, 2000);
    if( n < 0 )
    {   
        printf("ERROR on poll");
        continue;
    }
    if(n == 0)
    {
        printf("waiting....\n");
        continue;
    }
    for(i = 0; i < N; i++)
    {
        char buff[1024]; <---i dont want to do this

        if (pfd[i].revents & POLLIN)
        {
            printf("Processing input....\n");
            read(pfd[i].fd, buff, O_NONBLOCK);
            readBattlefield(buff);
            print_battleField_stats();
            pfd[i].fd = 0;
        }
    }
}

i also read somewhere that once read() reads all the data coming, it empties the pipe, meaning i can use the same again for another incoming data. but it doesnt empty the pipe because i cant use the same pipe again. I asked my professor but all he says was to use something like scanf, but how do use scanf if scanf takes a FILE stream, and the poll.fd is an int? essentially my ultimate question is, how to read the incoming data through the file descriptor using scan or of other sort? using scan will help me more with handling the data.

EDIT:
in another terminal i have to put cat file > (named_file)
and my main program will read the input data. heres what the input data looks like

3 3

1 2 0

0 2 0

3 0 0

first 2 numbers are grid information and player number, and after that is grid, but this a simplified version, ill be dealing with sizes over 100's of players and grids of over 1000's

Best Answer

char buff[1024]; <---i dont want to do this

What would you like to do then? This is how it works. This is not how it works:

read(pfd[i].fd, buff, O_NONBLOCK);

This will compile because O_NONBLOCK is an integer #define, but it is absolutely and unequivocally incorrect. The third argument to read() is a number of bytes to read. Not a flag. Period. It may be zero, but what you've done here is pass an arbitrary number -- whatever the value of O_NONBLOCK is, which could easily be more than 1024, the size of your buffer. This does not set the read non-block. recv() is similar to read() and does take such flags as a forth argument, but you can't use that with a file descriptor. If you want to set non-block on a file descriptor, you must do it with open() or fcntl().

how to read the incoming data through the file descriptor using scan or of other sort?

You can create a FILE* stream from an open descriptor with fdopen().

i also read somewhere that once read() reads all the data coming, it empties the pipe, meaning i can use the same again for another incoming data. but it doesnt empty the pipe because i cant use the same pipe again.

Once you reach EOF (because the writer closed the connection), read() will return 0, and continue to return 0 immediately until someone opens the pipe again.

If you set the descriptor non-block, read() will always return immediately; if there is someone connected and nothing to read, it will return -1 but errno will == EAGAIN. See man 2 read.

man fifo is definitely something you should read; if there's anything you aren't sure about, ask a specific question based on that.

And don't forget: Fix that read() call. It's wrong. W R O N G. Your prof/TA/whoever will not miss that.

Related Topic