How can you generate a POLLPRI event in a regular file?

When working with sysfs GPIO on Linux, you are told poll for the POLLPRI and POLLERR .

It is pretty simple:

 poll = select.poll() poll.register(filename, select.POLLPRI | select.POLLERR) result = poll.poll(timeout=timeout) 

However, I would like to write tests for this code and simulation tests for the application, relying on it. So, I need to be able to trigger the POLLPRI event.

I tried using a Unix domain socket, but then I can’t open the file for reading after connecting the domain socket ( errno 6 , no such device). I also tried using a socket with SOCK_DGRAM , but either could not find the file if it was not already created, or the connection failed.

I want to open a regular file or create a file that can be opened as a regular file, and be able to send him a stream of messages that are considered “urgent data”. those. MSG_OOB

What can I do?

+6
source share
1 answer

It looks like you can achieve this by polling the sysctl that was discovered in procfs. If you look at the poll implementation in procfs for the sys subdirectory , you will see that any sysctl that implements polling notifications will return a mask that includes POLLERR|POLLPRI . So, how do we find out that sysctls implement this? We are looking for using proc_sys_poll_notify !

One such place is located in proc_do_uts_string , which implements the sysctls series in /proc/sys/kernel . Most of them are read-only, but hostname and domainname can be written (see also their records).

Of course, this will require that root privileges can be written, for example. /proc/sys/kernel/hostname .

This is probably the easiest way to do such a thing, while remaining within the scope of the synthetic file system implementation. Of course, the only real way to test your code is to poll(2) one of your contacts, press a button and see if the up / down signals are interrupted.

Note: sysfs also does this for edge nodes in the tree :

 >>> import select >>> f = open('/sys/bus/clockevents/devices/clockevent0/uevent', 'r') >>> p = select.poll() >>> p.register(f, select.POLLPRI | select.POLLERR) >>> result = p.poll(10) >>> result [(3, 10)] 

10 course POLLPRI (0x2) | POLLERR (0x8) POLLPRI (0x2) | POLLERR (0x8) . I got the same results using /sys/power/state as my input. Basically, if you query any user entry that is not related to directories in sysfs, you will get POLLPRI | POLLERR POLLPRI | POLLERR back.

+2
source

Source: https://habr.com/ru/post/980222/


All Articles