Project

General

Profile

Actions

Bug #20708

closed

EINTR while opening fifo isn't retried

Added by martin.dorey@hds.com (Martin Dorey) 3 months ago. Updated 3 months ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.4.0dev (2024-08-30T20:36:28Z master eef2121cf3) [x86_64-linux]
[ruby-core:118996]

Description

I don't think this should fail:

martind@stormy:~/download/ruby$ rm -f /tmp/badger && mkfifo /tmp/badger && timeout 2 ./ruby --disable-gems -we 'fork() {}; IO.read("/tmp/badger")'
-e:1:in 'IO.read': Interrupted system call @ rb_sysopen - /tmp/badger (Errno::EINTR)
	from -e:1:in '<main>'
martind@stormy:~/download/ruby$

The behavior changed with 2.6.0-preview3 compared to 2.6.0-preview2:

martind@stormy:~/download/ruby-2.6.0-preview2$ rm -f /tmp/badger && mkfifo /tmp/badger && timeout 2 ./ruby --disable-gems -we 'fork() {}; IO.read("/tmp/badger")'
martind@stormy:~/download/ruby-2.6.0-preview3$ rm -f /tmp/badger && mkfifo /tmp/badger && timeout 2 ./ruby --disable-gems -we 'fork() {}; IO.read("/tmp/badger")'
Traceback (most recent call last):
	1: from -e:1:in `<main>'
-e:1:in `read': Interrupted system call @ rb_sysopen - /tmp/badger (Errno::EINTR)
martind@stormy:~/download/ruby-2.6.0-preview3$ 

I don't know what the consequences would be, so I don't mean this as a serious suggestion:

martind@stormy:~/download/ruby$ git diff
diff --git a/io.c b/io.c
index 54b60b7357..590e8d11d7 100644
--- a/io.c
+++ b/io.c
@@ -6956,7 +6956,10 @@ sysopen_func(void *ptr)
 static inline int
 rb_sysopen_internal(struct sysopen_struct *data)
 {
-    int fd = IO_WITHOUT_GVL_INT(sysopen_func, data);
+    int fd;
+    do {
+        fd = IO_WITHOUT_GVL_INT(sysopen_func, data);
+    } while (fd < 0 && errno == EINTR);
     if (0 <= fd)
         rb_update_max_fd(fd);
     return fd;
martind@stormy:~/download/ruby$ 

... but it fixes this particular test case, for me, with today's Ruby from github.

There were negligible differences between 2.6.0-preview{2,3} in io.c but the SIGCHLD handling was changed.

The test case is reliable for me on at least:

Linux stormy 4.19.0-26-amd64 #1 SMP Debian 4.19.304-1 (2024-01-09) x86_64 GNU/Linux
Linux moritz 5.10.0-14-amd64 #1 SMP Debian 5.10.113-1 (2022-04-29) x86_64 GNU/Linux

I hope it's independent of the kernel, as:

https://man7.org/linux/man-pages/man7/signal.7.html

... teaches:

otherwise the call fails with the error EINTR:
...
• open(2), if it can block (e.g., when opening a FIFO; see
fifo(7)).

Actions

Also available in: Atom PDF

Like0
Like0Like0