From 790571a2cd5e1e7187500a356e587716bf1fd810 Mon Sep 17 00:00:00 2001 From: Casper Dik Date: Sun, 1 Aug 2021 12:43:19 -0700 Subject: [PATCH 1/2] gspawn: safe_closefrom for Solaris 11.3/11.4 When F_CLOSEFROM is defined, we know that closefrom() is signal safe. --- glib/gspawn.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/glib/gspawn.c b/glib/gspawn.c index 3073a10a4..c75619c08 100644 --- a/glib/gspawn.c +++ b/glib/gspawn.c @@ -1487,7 +1487,8 @@ safe_fdwalk (int (*cb)(void *data, int fd), void *data) static void safe_closefrom (int lowfd) { -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || \ + (defined(__sun__) && defined(F_CLOSEFROM)) /* Use closefrom function provided by the system if it is known to be * async-signal safe. * @@ -1496,6 +1497,9 @@ safe_closefrom (int lowfd) * * OpenBSD: closefrom is not included in the list, but a direct system call * should be safe to use. + * + * In Solaris as of 11.3 SRU 31, closefrom() is also a direct system call. + * On such systems, F_CLOSEFROM is defined. */ (void) closefrom (lowfd); #elif defined(__DragonFly__) From a75ffc51120b328d95df960eb00e2637efb9df65 Mon Sep 17 00:00:00 2001 From: Casper Dik Date: Sun, 1 Aug 2021 12:45:13 -0700 Subject: [PATCH 2/2] gspawn: safe_fdwalk for Solaris 11.4 Use F_NEXTFD/F_PREVFD for fdwalk when they are available. Closes #2429 --- glib/gspawn.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/glib/gspawn.c b/glib/gspawn.c index c75619c08..3f432a576 100644 --- a/glib/gspawn.c +++ b/glib/gspawn.c @@ -1444,6 +1444,27 @@ safe_fdwalk (int (*cb)(void *data, int fd), void *data) #endif +#if defined(__sun__) && defined(F_PREVFD) && defined(F_NEXTFD) +/* + * Solaris 11.4 has a signal-safe way which allows + * us to find all file descriptors in a process. + * + * fcntl(fd, F_NEXTFD, maxfd) + * - returns the first allocated file descriptor <= maxfd > fd. + * + * fcntl(fd, F_PREVFD) + * - return highest allocated file descriptor < fd. + */ + + open_max = fcntl (INT_MAX, F_PREVFD); /* find the maximum fd */ + if (open_max < 0) /* No open files */ + return 0; + + for (fd = -1; (fd = fcntl (fd, F_NEXTFD, open_max)) != -1; ) + if ((res = cb (data, fd)) != 0 || fd == open_max) + break; +#else + #if 0 && defined(HAVE_SYS_RESOURCE_H) /* Use getrlimit() function provided by the system if it is known to be * async-signal safe. @@ -1477,6 +1498,7 @@ safe_fdwalk (int (*cb)(void *data, int fd), void *data) for (fd = 0; fd < open_max; fd++) if ((res = cb (data, fd)) != 0) break; +#endif return res; #endif