[Openmcl-devel] popen is not happy
Gary Byers
gb at clozure.com
Wed Jun 4 12:59:20 PDT 2003
On Wed, 4 Jun 2003, Erann Gat wrote:
>
> This works fine:
>
> ? (with-cstrs ((s1 "ls")) (#_system s1))
> LGPL bindarwin doc dppccl.image scripts
> LICENSE darwin-headers dppccl library
> 0
> ?
Recall that WITH-CSTRs stack-allocates one or more C strings, and
that #_system does some flavor of #_fork followed by some flavor of
#_exec, and returns 0 if this all succeeds; the (fork) parent process
waits around until the #_fork succeeds and the #_exec'ed process
exits, so there's no possibility of the stack-allocated strings being
deallocated before the #_fork/#_exec happen.
>
> This doesn't work so good:
>
> ? (with-cstrs ((s1 "ls") (s2 "r+")) (#_popen s1 s2))
> #<A Null Mac Pointer>
> ?
>
> ...
>
> ? (with-cstrs ((s1 "ls") (s2 "r")) (#_popen s1 s2))
> Unhandled exception 11 at 0x900336a4, context->regs at #xbffff648
> Continue/Debugger/eXit <enter>?
> X
I'm less convinced that it's safe to pass stack-allocated strings to
#_popen; whether this works or not may depend on whether the forked
child is able to use them before the parent deallocates them. It
looks very much like the exception you got here was in the child
process; typing an "X" at the prompt killed the child process, and
the pipe-based FILE* was returned to the parent process.
I wasn't able to get this to fail, but I was trying under Linux
(whose #_popen and #_fork functions may behave a bit differently.)
If it works to heap-allocate the C string (via MAKE-CSTRING), then
the next question would involve understanding a bit more about how
#_popen works. #_popen is supposed to return a FILE* unless the
#_pipe or #_fork calls fail; that doesn't really tell us when it's
safe to deallocate a string that may be shared between the forked
child and parent.
> #<A Mac Pointer #xA0006B0C>
> ? (setf p *)
> #<A Mac Pointer #xA0006B0C>
> ? (#_fileno p)
> 8
> ? (make-instance 'fd-stream :fd 8)
>
> [hang]
>
> Is this a bug, or am I doing something wrong?
>
Both.
The easiest way to make an FD-STREAM is via MAKE-FD-STREAM:
MAKE-FD-STREAM fd &key (direction :input)
(interactive t)
(elements-per-buffer *elements-per-buffer*)
(element-type 'character)
(class 'fd-stream)
It's a bit harder to create one via MAKE-INSTANCE, though doing so
shouldn't hang, obviously.
> E.
>
>
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/cgi-bin/mailman/listinfo/openmcl-devel
>
>
_______________________________________________
Openmcl-devel mailing list
Openmcl-devel at clozure.com
http://clozure.com/cgi-bin/mailman/listinfo/openmcl-devel
More information about the Openmcl-devel
mailing list