This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch reproducible-widget-previews
in repository efl.

View the commit online.

commit 326f9717a95e63069c9de5769766a5ec35a419c9
Author: Cedric BAIL <[email protected]>
AuthorDate: Tue Mar 17 17:50:23 2026 -0600

    eina: fix eina_file_close_from corrupting fds on macOS after fork
    
    The opendir/readdir/seekdir path used on macOS is not async-signal-safe.
    When called between fork() and exec() in a multi-threaded Cocoa process,
    the C library internal locks may be in an inconsistent state, causing
    memory corruption that closes fds 0 and 1 (the PTY slave stdin/stdout).
    
    This broke child shell processes in terminal emulators: bash would see
    stdin as a non-terminal, read EOF, and exit immediately with code 0.
    
    Use a simple brute-force close loop on macOS instead, which only calls
    close() -- an async-signal-safe function that works reliably after fork.
    
    Made-with: Cursor
---
 src/lib/eina/eina_file_posix.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/src/lib/eina/eina_file_posix.c b/src/lib/eina/eina_file_posix.c
index 2947ed6c34..351f6d0e59 100644
--- a/src/lib/eina/eina_file_posix.c
+++ b/src/lib/eina/eina_file_posix.c
@@ -1305,6 +1305,33 @@ eina_file_close_from(int fd, int *except_fd)
 {
 #if defined(_WIN32)
    // XXX: what do to here? anything?
+#elif defined(__APPLE__)
+   /* On macOS this function is called between fork() and exec() in a
+    * multi-threaded Cocoa process.  The opendir/readdir/seekdir path is
+    * NOT async-signal-safe and corrupts the file-descriptor table when
+    * the C library's internal locks are in an inconsistent state after
+    * fork().  Use the simple brute-force close loop instead. */
+   {
+      int i, j, max = 1024;
+#ifdef HAVE_SYS_RESOURCE_H
+      struct rlimit lim;
+      if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_max != RLIM_INFINITY)
+        max = lim.rlim_max;
+#endif
+      for (i = fd; i < max; i++)
+        {
+           if (except_fd)
+             {
+                Eina_Bool skip = EINA_FALSE;
+                for (j = 0; except_fd[j] >= 0; j++)
+                  {
+                     if (except_fd[j] == i) { skip = EINA_TRUE; break; }
+                  }
+                if (skip) continue;
+             }
+           close(i);
+        }
+   }
 #else
 #ifdef HAVE_DIRENT_H
 //# if 0

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to