lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Mon, Apr 23, 2012 at 22:33, Sean Conner <sean@conman.org> wrote:
> It was thus said that the Great Rena once stated:
>> On Mon, Apr 23, 2012 at 10:52, Jay Carlson <nop@nop.com> wrote:
>> > On Mon, Apr 23, 2012 at 9:25 AM, Robert Klemme
>> >
>> > IMO on Unix if you want to play the part of a shell, the problem comes
>> > down to embedding a reasonable domain-specific quasiquotation syntax
>> > for constructing process invocation structures. Which would you rather
>> > write?
>> >
>> >  proc{'find', "/usr", "-name", pattern, "-print0"}.pipe{'xargs', '-0', 'du'}()
>> >
>> >  find /usr -name "$pattern" -print0 | xargs -0 du
>> >
>> >  find /usr -name $pattern -print0 | xargs -0 du
>>
>> My thought would be something a little more verbose, like:
>> proc1 = create_process('find', {path='/usr', name=pattern, print0=true})
>> proc2 = create_process('xargs', {nullsep=true, delim='u'})
>> proc1.stdin = proc2.stdout
>> proc2:start(); proc1:start()
>
>  Another approach is to create a "Unix program userdata type" [4].  Perhaps
> something like:
>
>        run(
>             cmd("find",{ "/usr" , "-name" , pattern , "-print0" })
>             .. cmd("xargs",{ "-0" }) ..
>             .. cmd("du") > "output.txt"
>        )
>
>  But I wouldn't want to type that at an interactive prompt.
>
>> (create_process would create but not start; you'd have another
>> function to create and start.)
>
>  If you are using Unix [1] as the kernel, it is impossible to create a
> process and not start it.  Or rather, I don't think you know how process
> creation under Unix works.  To create a new process, you call fork():
>
>        pid_t child;
>
>        child = fork();
>        if (child == -1)
>          /* there was an error creating the process */
>        else if (child == 0)
>          /* we are the newly created child process */
>        else
>          /* we just created a new process */
>
> Yes, the new process is a duplicate of the process that created it [2].  To
> *run* a different program, you have to call exec() [3], which overlays the
> calling program with the new program.  The call exec() never returns unless
> there's an error.  A typical pattern to run a program in another process is
> to:
>
>        child = fork();
>        if (child == -1)
>          handle_error();
>        else if (child == 0)
>        {
>          execve("/path/to/program",argv,envp);
>          handle_error();
>          _exit(1);
>        }
>        else
>        {
>          /* either wait for the child process to end, or go on */
>          /* and do something else ... */
>        }
>
> It might seem silly to require two system calls to do one job, but there are
> some good reasons for it [2a].
>
>  -spc
>
> [1]     This include Linux, the various BSDs and Mac-OS X.
>
> [2]     It's always been this way under Unix.  From some personal
>        correspondence with Dennis Ritchie about the fork() system call:
>
>                At the time,  the trap instruction corresponding to `sys
>                fork' (if I remember correctly) probably skipped an
>                instruction in either the parent or the child to indicate
>                the difference, and the slot perforce was usually filled
>                with a branch to separate the parent and child.
>
>                ...
>
> [2a]            The design of the fork primitive was somewhat adventitious,
>                but it turned out that splitting the creation of the new
>                process into two threads executing the same program (though
>                with copied data) before the typical execution of a new
>                program in the child is quite convenient.  For example, it
>                gives the shell (say) a chance to redirect its I/O in the
>                child process before handing control to the newly executed
>                program.
>
> [3]     It's actually one of six functions, execve() being the actual system
>        call.
>
> [4]     I did something similar to this in a language I wrote in college.  I
>        made Unix commands a first-class data type.
>

Huh, no way to create a process without immediately starting it? That
seems like a bit of a shortfall. IIRC even the Windows kernel can do
that. ;-)

-- 
Sent from my toaster.