On 22.11.2012, at 12:28, Igor Stasenko <siguctua@gmail.com> wrote:
On 22 November 2012 11:19, Max Leske <maxleske@gmail.com> 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).
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 <maxleske@gmail.com> wrote:
On 20.11.2012, at 21:56, David T. Lewis <lewis@mail.msen.com> 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.