On 22.11.2012, at 17:00, Igor Stasenko <[email protected]> wrote:
> On 22 November 2012 16:34, David T. Lewis <[email protected]> wrote:
>> On Thu, Nov 22, 2012 at 04:04:00PM +0100, Max Leske wrote:
>>>
>>> On 22.11.2012, at 12:28, Igor Stasenko <[email protected]> wrote:
>>>
>>>> On 22 November 2012 11:19, Max Leske <[email protected]> wrote:
>>>>> I have run into a small problem with fork():
>>>>>
>>>>> pid := self primitiveRun.
>>>>> pid isZero
>>>>> ifTrue: [ "child code with exec" ]
>>>>> ifFalse: [ "parent code" ]
>>>>>
>>>>> primitiveRun
>>>>> <primitive: #primitiveNativeCall module: #NativeBoostPlugin>
>>>>> ^ self nbCall: #( int fork() )
>>>>>
>>>>> Only the parent code is ever executed, #pid is never 0.
>>>>
>>>> are you sure about that?
>>>> if you evaluate
>>>> self fork
>>>> it will always answer non-zero.. because it is parent process,
>>>> where you observing result.
>>>> But that doesnt means that there is no child process which observes
>>>> different return value.
>>>
>>> Assuming that I wouldn't be able to observer when #pid is 0, then the
>>> following should still work:
>>>
>>> pid := self primitiveRun.
>>> pid isZero
>>> ifTrue: [ StandardFileStream forceNewFileNamed: 'foo.log' ]
>>> <-----------------------
>>> ifFalse: [ "parent code" ]
>>>
>>> The file 'foo.log' is never created.
>>>
>>> The UnixOSProcessPlugin has pretty much the same code:
>>>
>>> ((pid := self cCode: 'vfork()') = 0)
>>> ifFalse:
>>> [ "child code" ]
>>> ifTrue:
>>> [ "parent code" ]
>>>
>>> BTW: using vfork() instead of fork() (as OSProcess does) doesn't work
>>> either (the image hangs as expected but the file 'foo.log' is not created).
>>>
>>
>> Assuming that you are trying to do a fork followed by exec,
That's the plan, although I'll have to do some stuff with the pipes before
exec'ing.
>> you will want to
>> do the exec immediately after the fork. This may introduce some complications
>> when you do it as two FFI calls, because your child process is still running
>> Smalltalk on the VM, and it needs to keep running long enough to the second
>> FFI call. Opening a new file stream on 'foo.log' implies a *lot* of
>> processing
>> in the child VM, so I am not surprised that this does not work.
>>
>> You might try just making a little "hello world" C program, and see if you
>> can exec that program after doing the fork. That would be a lot less
>> processing
>> for your child VM, so it may have a better chance of working. But you still
>> may have a few issues to sort out in keeping the child VM running long enough
>> to get the the exec FFI call.
>>
Ok. Not quite sure how that all works but I tried to come up with a program
that is as short as possible:
run
| pid args |
args := (LimboCommand new
command: '/bin/echo';
arguments: { 'foo' })
primitiveArguments.
pid := self primitiveRun.
pid isZero
ifTrue: [ self primitiveExecv: args first arguments: args ]
ifFalse: [ "parent code" ].
Still not working. fork() does create the child process but it won't exec
(because it never reaches that point in execution somehow) and I can't kill the
child process on the command line (have to close the image; the childs are not
zombies)
>
> aye... and with a bit of assembler black magic you can actually
> generate a code to call
> those two functions in same primitive, so you don't leave to interpreter at
> all.
Cool :) Will be my last resort though.
Regarding the "hanging" image: yes the child process is created but as the man
page for fork() states that the parent will be suspended until the child is
exec'ed. Therefore, having the image "hang" is expected because I can't exec
the child.
Thanks for the help guys.
Max
>
> bit still it would be nice if it could work using two separate FFI calls.
>
>> Dave
>>
>>>
>>>>
>>>>> Looking at UnixOSProcessPlugin I see that there are some special things
>>>>> Dave did before forking and I'm wondering if these would be necessary
>>>>> with NB. In the method #forkAndExecInDirectory:
>>>>> 1. possible use of a sig handler
>>>>> 2. special secure mode handling (what's that?)
>>>>> 3. turn off the interval timer
>>>>>
>>>>> Any ideas?
>>>>>
>>>>> Cheers,
>>>>> Max
>>>>>
>>>>> On 21.11.2012, at 08:50, Max Leske <[email protected]> wrote:
>>>>>
>>>>>>
>>>>>> On 20.11.2012, at 21:56, David T. Lewis <[email protected]> wrote:
>>>>>>
>>>>>>> On Mon, Nov 19, 2012 at 05:46:14PM -0300, Igor Stasenko wrote:
>>>>>>>>
>>>>>>>> Providing bindings to fork/pipe kernel functions is piece of cake.
>>>>>>>> But writing a wrapper around it would be a bit of work.. but still it
>>>>>>>> is possible. And you should try.
>>>>>>>>
>>>>>>>> And yes, using fork() stuff having many treacherous pitfalls, but
>>>>>>>> don't think that if you call this function from code written in C
>>>>>>>> instead of NB will make it less treacherous.
>>>>>>>> I think Dave can give some more input on that, because he also using
>>>>>>>> fork() in OSProcess.
>>>>>>>
>>>>>>> In normal use, the fork() call is immediately followed by an exec(), so
>>>>>>> it is not tricky at all. The only thing that was tricky to do in
>>>>>>> OSProcess
>>>>>>> was forkSqueak() which forks the VM itself and then attempts to continue
>>>>>>> running. But that is really an unusual use case.
>>>>>>>
>>>>>>> The system calls such as fork() and pipe() should work the same whether
>>>>>>> you are calling from FFI or from generated C in a primitive. You can
>>>>>>> find examples for many of these calls in OSProcess. In general, the
>>>>>>> interface to system calls and standard C library functions is in
>>>>>>> UnixOSProcessPlugin, and the associated glue to tie it into the image
>>>>>>> is in UnixOSProcessAccessor. I have not looked at it closely but I
>>>>>>> think that in some cases you could change the methods in
>>>>>>> UnixOSProcessAccessor
>>>>>>> to make FFI calls, at least in order to get something working initially
>>>>>>> (I don't know if the design of OSProcess is what you want, but it could
>>>>>>> get you started).
>>>>>>>
>>>>>> Thanks Dave, that's good to know.
>>>>>>
>>>>>> Cheers,
>>>>>> Max
>>>>>>
>>>>>>> Dave
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Best regards,
>>>> Igor Stasenko.
>>>>
>>>
>>
>
>
>
> --
> Best regards,
> Igor Stasenko.
>