3

Dear StackExchange members,

I recently began toying around with Common Lisp and want to create a web interface for administrating a modded Minecraft server. I already tried out this solution but in this case the function just hangs and never returns.

My code looks like this:

(defvar *proc*)

(defun create-minecraft-proc ()
  (let* ((binary "/usr/bin/java")
    (jar "/home/user/temp/Vanilla 1.8/minecraft.jar")
    (dir "/home/user/temp/Vanilla 1.8")
    (args (list "-jar" jar "nogui")))
    (setf *proc* (sb-ext:run-program binary args :directory dir :wait nil :input :stream :output :stream))))

(defun copy-stream (in out)
  (loop for line = (read-line in nil nil)
     while line
       do (write-line line out)))

(defun get-minecraft-output ()
  (with-open-stream (proc-stream (process-output *proc*))
    (with-output-to-string (out)
      (copy-stream (process-output *proc*) out)))

How can I get a string containing the complete process output till that time without having to wait for it to terminate?

Community
  • 1
  • 1
Sojaki
  • 187
  • 1
  • 8

1 Answers1

4

Experimenting with /bin/cat, I found some things that might help you.

First, of all, always use finish-output after writing to the process's input:

(format (process-input *cat*) "Hello~%")
(finish-output (process-input *cat*))

Otherwise, the input may not reach the subprocess until you close the input stream. If Minecraft requires input before it'll generate any output, then trying to read from its output without the required input would result in SBCL hanging in a way that can't be recovered with C-c C-c in SLIME.

Second, use listen to determine if any output has been generated:

(when (listen (process-output *cat*))
    (read-line (process-output *cat*)))

With finish-output and listen, I was able to avoid hanging while incrementally reading from cat's stdout.

Throw Away Account
  • 2,593
  • 18
  • 21
  • That worked perfectly, thanks a lot. Especially the part about finish-output because the next thing I was going to do was to send commands to the Minecraft server. – Sojaki May 24 '15 at 07:58