--- glib/gspawn.c.orig 2019-07-19 22:50:54.355429000 +0200 +++ glib/gspawn.c 2019-07-20 00:27:16.789113000 +0200 @@ -39,6 +39,13 @@ #include #endif /* HAVE_SYS_RESOURCE_H */ +#ifdef __FreeBSD__ +#include +#include +#include +#include +#endif + #include "gspawn.h" #include "gthread.h" #include "glib/gstdio.h" @@ -1126,7 +1133,37 @@ * rlimit trick */ #endif + +#ifdef __FreeBSD__ + char *bp = NULL; + char *ep = NULL; + size_t len = 0; + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC, (int)getpid()}; + if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == 0) + { + bp = (char*) malloc(len); + if (sysctl(mib, nitems(mib), bp, &len, NULL, 0) == 0) + { + ep = bp; + while (ep < bp + len) { + struct kinfo_file kif = *(struct kinfo_file*)ep; + ep += kif.kf_structsize; + if (kif.kf_fd < 0) + continue; + + if ((res = cb (data, kif.kf_fd)) != 0) + break; + } + + free(bp); + return res; + } + free(bp); + } + /* If any sysctl call fails continue with the fall back method */ +#endif + #ifdef HAVE_SYS_RESOURCE_H if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY)