View | Details | Raw Unified | Return to bug 240548 | Differences between
and this patch

Collapse All | Expand All

(-)x11-toolkits/vte3/files/patch-src_vtespawn.cc (+99 lines)
Line 0 Link Here
1
--- src/vtespawn.cc	2018-09-21 12:29:23.000000000 +0300
2
+++ src/vtespawn.cc	2019-07-20 18:05:15.486558000 +0300
3
@@ -36,6 +36,12 @@
4
 #include <sys/resource.h>
5
 #endif /* HAVE_SYS_RESOURCE_H */
6
 
7
+#ifdef __FreeBSD__
8
+#include <sys/param.h>
9
+#include <sys/sysctl.h>
10
+#include <sys/user.h>
11
+#endif
12
+
13
 #include <glib-unix.h>
14
 
15
 #include "vtespawn.hh"
16
@@ -410,7 +416,70 @@
17
 }
18
 
19
 #ifndef HAVE_FDWALK
20
+
21
+#ifdef __FreeBSD__
22
 static int
23
+fdwalk2(int (*func)(void *, int), void *udata, int *ret) {
24
+  char *buf = NULL, *buf_end, *ptr;
25
+  size_t bufsz = 0, tmp = 0;
26
+  struct kinfo_file *kf;
27
+  int uret = 0;
28
+  int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC, 0 };
29
+
30
+  if (func == NULL)
31
+    return EINVAL;
32
+
33
+  /* Get files info. */
34
+  mib[3] = (int) getpid ();
35
+  for (;;) {
36
+    if (0 != sysctl (mib, nitems(mib), NULL, &bufsz, NULL, 0)) {
37
+err_out:
38
+      free(buf);
39
+      return errno;
40
+    }
41
+    ptr = (char *) realloc (buf, bufsz);
42
+    if (ptr == NULL)
43
+      goto err_out;
44
+    buf = ptr;
45
+    if (sysctl (mib, nitems(mib), buf, &bufsz, NULL, 0) == 0) {
46
+      /* https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=240573
47
+       * If new files opened before next sysctl() call
48
+       * then kernel silently truncate result data.
49
+       * Re check required size to decrease chances
50
+       * to lost data. */
51
+      if (sysctl (mib, nitems(mib), NULL, &tmp, NULL, 0) != 0)
52
+        goto err_out;
53
+      if (tmp > bufsz)
54
+        continue; /* More files opened, retry. */
55
+      break; /* Ok. */
56
+    }
57
+    if (errno != ENOMEM)
58
+      goto err_out;;
59
+  }
60
+
61
+  /* Walk. */
62
+  buf_end = (buf + bufsz);
63
+  for (ptr = buf; ptr < buf_end; ptr += kf->kf_structsize) {
64
+    kf = (struct kinfo_file *) (void *) ptr;
65
+    if (kf->kf_structsize == 0)
66
+      break;
67
+    if (kf->kf_fd < 0)
68
+      continue;
69
+    uret = func (udata, kf->kf_fd);
70
+    if (uret != 0)
71
+      break;
72
+  }
73
+  free (buf);
74
+
75
+  if (ret != NULL) {
76
+    (*ret) = uret;
77
+  }
78
+
79
+  return 0;
80
+}
81
+#endif
82
+
83
+static int
84
 fdwalk (int (*cb)(void *data, int fd), void *data)
85
 {
86
   gint open_max;
87
@@ -419,6 +488,12 @@
88
   
89
 #ifdef HAVE_SYS_RESOURCE_H
90
   struct rlimit rl;
91
+#endif
92
+
93
+#ifdef __FreeBSD__
94
+  if (fdwalk2(cb, data, &res) == 0)
95
+      return res;
96
+  /* If any sysctl/malloc call fails continue with the fall back method */
97
 #endif
98
 
99
 #ifdef __linux__  

Return to bug 240548