emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/3] Inherit process output coding system to stderr process.


From: Philipp Stephani
Subject: [PATCH 3/3] Inherit process output coding system to stderr process.
Date: Wed, 4 Apr 2018 14:02:18 +0200

* src/process.c (Fmake_process): Inherit output coding system to
newly-created pipe process.

* test/src/process-tests.el (make-process/stderr-coding)
(make-process/mixed-output-coding): New unit tests.
---
 src/process.c             |  7 ++++
 test/src/process-tests.el | 76 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/src/process.c b/src/process.c
index dcc9dcb31e..2b3e00d423 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1698,12 +1698,15 @@ usage: (make-process &rest ARGS)  */)
   bool query_on_exit = NILP (Fplist_get (contact, QCnoquery));
 
   stderrproc = Qnil;
+  bool stderr_inherit_coding_system;
   xstderr = Fplist_get (contact, QCstderr);
   if (PROCESSP (xstderr))
     {
       if (!PIPECONN_P (xstderr))
        error ("Process is not a pipe process");
       stderrproc = xstderr;
+      /* Use the coding system passed to `make-pipe-process'.  */
+      stderr_inherit_coding_system = false;
     }
   else if (!NILP (xstderr))
     {
@@ -1717,6 +1720,8 @@ usage: (make-process &rest ARGS)  */)
                          query_on_exit ? Qnil : Qt,
                          QCsentinel,
                          Qignore);
+      /* Inherit the output coding system from the main process.  */
+      stderr_inherit_coding_system = true;
     }
 
   proc = make_process (name);
@@ -1808,6 +1813,8 @@ usage: (make-process &rest ARGS)  */)
          val = XCAR (Vdefault_process_coding_system);
       }
     pset_decode_coding_system (XPROCESS (proc), val);
+    if (stderr_inherit_coding_system)
+      Fset_process_coding_system (stderrproc, val, Qno_conversion);
 
     if (!NILP (tem))
       {
diff --git a/test/src/process-tests.el b/test/src/process-tests.el
index 838ba78acb..828f4207e1 100644
--- a/test/src/process-tests.el
+++ b/test/src/process-tests.el
@@ -217,5 +217,81 @@ process-test-sentinel-wait-function-working-p
       (should (eq (process-exit-status process) 0))
       (should (equal (buffer-string) "stderr\n")))))
 
+(ert-deftest make-process/stderr-coding ()
+  "Check that `make-process' correctly encodes standard error."
+  (skip-unless (executable-find shell-file-name))
+  ;; The byte sequences printed to standard output and error are valid
+  ;; UTF-8 code unit sequences for "ä" and "ö", respectively.
+  ;; However, `make-process' should decode them both using
+  ;; `iso-latin-1-dos', as specified below.
+  (with-temp-buffer
+    (let ((stdout (current-buffer))
+          ;; `coding-system-for-read' should be ignored.
+          (coding-system-for-read 'utf-8-unix))
+      (with-temp-buffer
+        (let ((process (make-process
+                        :name "stderr-coding"
+                        :command (list shell-file-name shell-command-switch
+                                       (concat "echo -e '\\xC3\\xA4\\r'; "
+                                               "echo -e '\\xC3\\xB6\\r' >&2"))
+                        :buffer stdout
+                        :stderr (current-buffer)
+                        :sentinel #'ignore
+                        :coding 'iso-latin-1-dos
+                        :noquery t
+                        :connection-type 'pipe)))
+          (while (process-live-p process)
+            (accept-process-output process))
+          (let ((stderr-process (get-buffer-process (current-buffer))))
+            ;; FIXME: The following form should not be required.
+            (while (process-live-p stderr-process)
+              (accept-process-output stderr-process)))
+          (should (eq (process-status process) 'exit))
+          (should (eq (process-exit-status process) 0))
+          (should (equal (buffer-string) "\u00C3\u00B6\n"))))
+      (should (equal (buffer-string) "\u00C3\u00A4\n")))))
+
+(ert-deftest make-process/mixed-output-coding ()
+  "Check that `make-process' allows different coding systems for
+the output streams."
+  (skip-unless (executable-find shell-file-name))
+  ;; The byte sequences printed to standard output and error are valid
+  ;; UTF-8 code unit sequences for "ä" and "ö", respectively.
+  ;; However, `make-process' should decode them using the coding
+  ;; systems passed to `make-process' and `make-pipe-process',
+  ;; respectively.
+  (with-temp-buffer
+    (let ((stdout (current-buffer))
+          ;; `coding-system-for-read' should be ignored.
+          (coding-system-for-read 'utf-8-unix))
+      (with-temp-buffer
+        (let* ((stderr-process (make-pipe-process
+                                :name "stderr-coding stderr"
+                                :buffer (current-buffer)
+                                :sentinel #'ignore
+                                :coding 'iso-latin-1-unix
+                                :noquery t))
+               (process (make-process
+                         :name "stderr-coding"
+                         :command (list shell-file-name shell-command-switch
+                                        (concat "echo -e '\\xC3\\xA4\\r'; "
+                                                "echo -e '\\xC3\\xB6\\r' >&2"))
+                         :buffer stdout
+                         :stderr stderr-process
+                         :sentinel #'ignore
+                         :coding 'iso-latin-1-dos
+                         :noquery t
+                         :connection-type 'pipe)))
+          (while (process-live-p process)
+            (accept-process-output process))
+          ;; FIXME: Should the following be required?
+          (while (process-live-p stderr-process)
+            (accept-process-output stderr-process))
+          (should (eq (process-status process) 'exit))
+          (should (eq (process-exit-status process) 0))
+          (should (eq (process-status stderr-process) 'closed))
+          (should (equal (buffer-string) "\u00C3\u00B6\r\n"))))
+      (should (equal (buffer-string) "\u00C3\u00A4\n")))))
+
 (provide 'process-tests)
 ;; process-tests.el ends here.
-- 
2.17.0.484.g0c8726318c-goog




reply via email to

[Prev in Thread] Current Thread [Next in Thread]