]> git.eshelyaron.com Git - emacs.git/commitdiff
Add a regression test for Bug#24325.
authorPhilipp Stephani <phst@google.com>
Tue, 29 Dec 2020 17:18:28 +0000 (18:18 +0100)
committerPhilipp Stephani <phst@google.com>
Tue, 29 Dec 2020 17:19:38 +0000 (18:19 +0100)
* test/src/process-tests.el (process-tests/fd-setsize-no-crash): New
unit test.

test/src/process-tests.el

index e15ad47f968b16696c64ae0837447606993f08b3..daf49759500690ea4c5dd43e8042dfbb5c6168dc 100644 (file)
@@ -368,5 +368,40 @@ See Bug#30460."
   "Check that looking up non-existent domain returns nil"
   (should (eq nil (network-lookup-address-info "emacs.invalid"))))
 
+(ert-deftest process-tests/fd-setsize-no-crash ()
+  "Check that Emacs doesn't crash when trying to use more than
+FD_SETSIZE file descriptors (Bug#24325)."
+  (let ((sleep (executable-find "sleep"))
+        ;; FD_SETSIZE is typically 1024 on Unix-like systems.
+        (fd-setsize 1024)
+        ;; `make-process' allocates at least four file descriptors per process
+        ;; when using the pipe communication method.  However, it closes two of
+        ;; them in the parent process, so we end up with only two new
+        ;; descriptors per process.
+        (fds-per-process 2)
+        (processes ()))
+    (skip-unless sleep)
+    ;; Start processes until we exhaust the file descriptor set size.
+    (dotimes (i (1+ (/ fd-setsize fds-per-process)))
+      (let ((process
+             ;; Failure to allocate more file descriptors should signal
+             ;; `file-error', but not crash.  Since we don't know the exact
+             ;; limit, we ignore `file-error'.
+             (ignore-error 'file-error
+               (make-process :name (format "test %d" i)
+                             :buffer nil
+                             :command (list sleep "5")
+                             :coding 'no-conversion
+                             :noquery t
+                             :connection-type 'pipe))))
+        (when process (push process processes))))
+    ;; We should have managed to start at least one process.
+    (should processes)
+    (dolist (process processes)
+      (while (accept-process-output process))
+      (should (eq (process-status process) 'exit))
+      (should (eql (process-exit-status process) 0))
+      (delete-process process))))
+
 (provide 'process-tests)
 ;; process-tests.el ends here.