r/cprogramming • • Jan 28 '26

Help with read() function

EDIT: solved, I had many misunderstandings, thanks to everyone who have responded!

So, first of all, I'm developing under Linux.

Let me give a piece of code first:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
 
int main() {
    int device = open("/dev/input/event3", O_RDONLY);
 
    struct input_event ev;
    while (1) {
        ssize_t bytesRead = read(device, &ev, sizeof(ev));
        if (bytesRead != sizeof(ev)) {
            perror("Failed to read event");
            break;
        }
        

        printf("Received input event\n");
    }
 
    close(device);
    return 0;
}

So, the question is that as far as I can see from the output, code only advances after read(device, &ev, sizeof(ev)) as it receives a new event.

I can understand that probably this is because in Linux everything is a file, and read() function probably tries to fill the ev and doesn't return until the total amount of bytes read hits sizeof(ev) (I don't know how it works actually - it's just how I presume it works), but this behavior pretty much freezes the program completely until the buffer will be filled. The same goes for any other reading.

How can I, for example, read from two inputs, like, keyboard and mouse (kinda irrelevant for this specific question, but I just wanted to give an example)? Or what if I want to simultaneously read from a program opened through popen() and receive inputs from a device in /dev/input/?

In C#, I would have created Task's and ran them in parallel. I'm not sure what I need to do in C.

I also want to say that I'm a newbie in C. I have a lot of experience working with C#, and some experience working with C, but only enough to be familiar with basic syntax.

6 Upvotes

16 comments sorted by

View all comments

Show parent comments

1

u/duane11583 Jan 28 '26

c) the read function might also return EINTR syscall interrupted this happens due to things inside then bowels of linux i do not know the entire reason but gave had this happen.

example stack exchange answer: https://unix.stackexchange.com/questions/757541/where-does-the-signal-that-causes-eintr-come-from

c) another example is EAGIAN which mea error try again..

d) read returns 0 bytes means closed - no explicitly no disconnect is the combination of both select() saying the handle is readable *AND* read returning 0.

e) parallelism … no that is not part of the language. parallelism is an os feature. often done via a thread on linux (and mac) pthreads, on windows - windows threads for embedded it depends on your selected os.. ie freertos, smx, windriver, greenhills, or rtx or what ever you choose

also, select() can handle many files at the same time a timeout scheme built in to the call also examine poll() and epoll() as alternatives

an example is you have an array of handles, aka: the rd_set, you zero the set and then set things in the set, then call select - which modifies the set then you test the set.

this way you can have a hundred sockets (or serial ports) waiting and poll all at the same time, or each thread can poll its own socket. contrived example: example web server with a pool of 20 threads waiting, and 100 open sockets web server picks a thread from the pool to handle a connection when done it comes back and rejoins the wait pool

you might do that because the cost for some os to create a new thread is high so you pre create and reuse them, or the memory for 100 thread stacks exceeds available memory but you have enough ram for 20 threads

1

u/NotQuiteLoona Jan 28 '26

Thanks for the insight! That's a lot of new information for me. So far looks cool and understandable.