[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lua OS
- From: Rena <hyperhacker@...>
- Date: Mon, 23 Apr 2012 22:45:52 -0600
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.