|
47 | 47 | #include <utime.h>
|
48 | 48 | #endif
|
49 | 49 |
|
| 50 | +// For max_fd_count |
| 51 | +#if defined (_AIX) |
| 52 | +#include <procinfo.h> |
| 53 | +#endif |
| 54 | + |
50 | 55 | #include <mono/metadata/object-internals.h>
|
51 | 56 | #include <mono/metadata/w32process.h>
|
52 | 57 | #include <mono/metadata/w32process-internals.h>
|
@@ -1594,6 +1599,43 @@ is_managed_binary (const char *filename)
|
1594 | 1599 | return managed;
|
1595 | 1600 | }
|
1596 | 1601 |
|
| 1602 | +/** |
| 1603 | + * Gets the biggest numbered file descriptor for the current process; failing |
| 1604 | + * that, the system's file descriptor limit. This is called by the fork child |
| 1605 | + * in process_create. |
| 1606 | + */ |
| 1607 | +static inline guint32 |
| 1608 | +max_fd_count (void) |
| 1609 | +{ |
| 1610 | +#if defined (_AIX) |
| 1611 | + struct procentry64 pe; |
| 1612 | + pid_t p; |
| 1613 | + p = getpid (); // will be called by the child in process_create |
| 1614 | + // getprocs 3rd/4th arg is for getting the associated FDs for a proc, |
| 1615 | + // but all we need is just the biggest FD, which is in procentry64 |
| 1616 | + if (getprocs64 (&pe, sizeof (pe), NULL, 0, &p, 1) != -1) { |
| 1617 | + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, |
| 1618 | + "%s: maximum returned fd in child is %u", |
| 1619 | + __func__, pe.pi_maxofile); |
| 1620 | + return pe.pi_maxofile; // biggest + 1 |
| 1621 | + } |
| 1622 | +// TODO: Other platforms. |
| 1623 | +// * On Linux, we can just walk /proc/self/fd? Perhaps in that approach, |
| 1624 | +// you can also just enumerate and close FDs that way instead? |
| 1625 | +// * On macOS, use proc_pidinfo + PROC_PIDLISTFDS? See: |
| 1626 | +// http://blog.palominolabs.com/2012/06/19/getting-the-files-being-used-by-a-process-on-mac-os-x/ |
| 1627 | +// (I have no idea how this plays out on i/watch/tvOS.) |
| 1628 | +// * On the BSDs, there's likely a sysctl for this. |
| 1629 | +// * On Solaris, there exists posix_spawn_file_actions_addclosefrom_np, |
| 1630 | +// but that assumes we're using posix_spawn; we aren't, as we do some |
| 1631 | +// complex stuff between fork and exec. There's likely a way to get |
| 1632 | +// the FD list/count though (maybe look at addclosefrom source in |
| 1633 | +// illumos?) or just walk /proc/pid/fd like Linux? |
| 1634 | +#endif |
| 1635 | + // fallback to user/system limit if unsupported/error |
| 1636 | + return eg_getdtablesize (); |
| 1637 | +} |
| 1638 | + |
1597 | 1639 | static gboolean
|
1598 | 1640 | process_create (const gunichar2 *appname, const gunichar2 *cmdline,
|
1599 | 1641 | const gunichar2 *cwd, StartupHandles *startup_handles, MonoW32ProcessInfo *process_info)
|
@@ -1976,7 +2018,7 @@ process_create (const gunichar2 *appname, const gunichar2 *cmdline,
|
1976 | 2018 | dup2 (err_fd, 2);
|
1977 | 2019 |
|
1978 | 2020 | /* Close all file descriptors */
|
1979 |
| - for (i = eg_getdtablesize() - 1; i > 2; i--) |
| 2021 | + for (i = max_fd_count () - 1; i > 2; i--) |
1980 | 2022 | close (i);
|
1981 | 2023 |
|
1982 | 2024 | #ifdef DEBUG_ENABLED
|
|
0 commit comments