guile-user
[Top][All Lists]
Advanced

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

Question about an error with ports


From: Zelphir Kaltstahl
Subject: Question about an error with ports
Date: Thu, 10 Mar 2022 01:26:51 +0000

Hello Guile Users!

I have some code at https://notabug.org/ZelphirKaltstahl/guile-examples/src/63af5250aa5a45d68bc6bd2d6193d2a6fb127f24/shell/example-04-using-popen-get-out-and-error-with-ports.scm:

~~~~
(import (ice-9 popen)
        (ice-9 textual-ports)
        (ice-9 binary-ports)
        (ice-9 exceptions)
        (ice-9 receive)
        (ice-9 match))


;; Is this useful at all? Or is there a better way? Maybe
;; anything using the file descriptors directly?
(define read-from-write-to
  (lambda* (in-port out-port #:key (bytes-count 1024))
    "Read from an IN-PORT and write to OUT-PORT,
    BYTES-COUNT bytes at a time."
    (let loop ([bv (get-bytevector-n in-port bytes-count)])
      (cond
       [(eof-object? bv)
        (close-port out-port)]
       [else
        (put-bytevector out-port bv)]))))


;; Trying to allow the user to give output port and error
;; port to the function. But how to elegantly call it then?
(define run-command
  (lambda* (cmd
            #:key
            (cmd-out-port (current-output-port))
            (err-out-port (current-error-port)))
    (match-let ([(err-read . err-write) (pipe)]
                [stderr (current-error-port)])
      (with-error-to-port err-write
        (λ ()
          (let* (;; Run the actual command. If an error
                 ;; happens, it should write to the
                 ;; err-write port. Output of the command
                 ;; should be written to an output port,
                 ;; which corresponds to the input-port,
                 ;; which is returned by open-input-pipe.
                 [in-port (open-input-pipe cmd)]
                 ;; Read in block mode.
                 [_ignored (setvbuf in-port 'block)])
            ;; Write to caller given command output port.
            (read-from-write-to in-port cmd-out-port)
            ;; Close the port, to which the child process
            ;; was to write errors, as the child process has
            ;; finished (either successfully or
            ;; unsuccessfully, but definitely
            ;; finished). Close the error output port,
            ;; before reading from the corresponding error
            ;; read port.
            (close-port err-write)
            ;; Write to caller given error output port.
            (read-from-write-to err-read err-out-port)
            ;; Get the exit code of the command.
            (close-pipe in-port)))))))

;; Why does this exit? I guess because of writing something
;; to the current error port and that means "an error happened"?
;; But why do I get an error and what does the error tell me?
(run-command "echo 'bong' 1>&2")
~~~~

I have the following questions:

(1) Is the read-from-write-to procedure useful at all, or is there a better way to get all stuff from an input port and output it to an output port, avoiding possibly large string values?

(2) Why do I get an error and what does the error mean? And why does it quit the REPL entirely, instead of giving me that [1] thingy, indicating, that an error happened, but letting me continue with the REPL session?

(3) How would I elegantly call a function, which allows to optionally specify an output port and an error port, specifying both?

Best regards,
Zelphir

--
repositories: https://notabug.org/ZelphirKaltstahl




reply via email to

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