Subject: Re: sbcl run-program "/bin/sh"
From: rpw3@rpw3.org (Rob Warnock)
Date: Thu, 08 Jun 2006 04:24:00 -0500
Newsgroups: comp.lang.lisp
Message-ID: <pu-dnekOMcAtcRrZnZ2dnUVZ_tmdnZ2d@speakeasy.net>
Juho Snellman <jsnell@iki.fi> wrote:
+---------------
| fungsin.lui@gmail.com <fungsin.lui@gmail.com> wrote:
| > Attached are some sessions with sbcl and acl80 (which can run sh
| > without any problem) under linux 2.6.
| [...]
| > *  (run-program "/bin/sh" nil :input t :output t :wait t :pty nil)
| 
| In principle this looks like it should work, and does indeed work on a
| non-Linux system or (rather bizarrely) on Linux when a "strace -ff"
| has been attached to the sbcl process. Based on a little bit of
| poking, it looks like it's some sort of interaction with the shell's
| job control and the tty-backed fds that end up getting used for stdin
| / stdout. 
+---------------

Further confirmation of that is what I see in CMUCL-19c on FreeBSD:

    > (run-program "/bin/sh" nil :input t :output t :wait t :pty nil)
    sh: can't access tty; job control turned off
    $ date
    Thu Jun  8 02:04:19 PDT 2006
    $ tty
    /dev/ttype
    $ exit 12

    #<process 1434 :EXITED>
    > 

That is, it works, but "sh" complains about the job control environment.
[And, as you say, not at all on Linux (without tracing).]

I dug into this once before when I was having trouble piping
output from CMUCL into "less", and the problem there was that
"less" was unable to access /dev/tty to read the interactive
control input. ISTR something in "cmucl/src/runprog.c" that
gets used to run sub-processes... Yes, here it is. The problem
was the line marked[*]:

       pid_t
       spawn(char *program, char *argv[], char *envp[], char *pty_name,
	     int stdin, int stdout, int stderr)
       {
	   pid_t pid;
	   sigset_t set;
	   int fd;

	   pid = fork();
	   if (pid != 0)
	       return pid;

	   /* Put us in our own process group. */
[*]==>   setsid();
	   ...
       }

That line caused any "read()"s that "less" did from /dev/tty to
get EOFs [which meant I couldn't move around in the file; the whole
thing just scrolled to the end and "less" exited immediately].
I *think* my solution was to remove that line[1], which isn't
there in other programs I looked at which run sub-proccesses,
but my memory is blurry as to whether it worked completely.

Anyway, you [fungsin.lui] might look in that area...


-Rob

[1] I didn't rebuild CMUCL to do that [since I hadn't yet learned
    how at that point]. What I actually did instead was create a
    "my-runprog.c" containing a modified "my_spawn()", then compiled
    that into a "my-runprog.so" loaded with LOAD-FOREIGN, then
    hacked up a version of EXTENSIONS:RUN-PROGRAM that called
    "my_spawn" instead of "spawn".

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607