Jump to content

Fork: Difference between revisions

2,605 bytes added ,  12 years ago
Line 168:
=={{header|Fexl}}==
There are many levels at which I can address this task. I'll start from the lowest possible level:
<lang fexl>fork \pid
fork \pid
print "pid = ";print pid;nl;
</lang>
 
You'll see the output of two processes there, with the child process printing the 0:
{{out}}
<pre>
Line 179 ⟶ 176:
pid = 0
</pre>
The child process prints the 0, and the parent process prints the pid of that child, which in this case happened to be 10077.
 
At the next level up, we can define a "spawn" function which makes it easy to fork a child process and interact with its stdin, stdout, and stderr:
<lang fexl>
# (spawn child_fn next)
# Fork the child function as a process and return its pid, stdin, stdout, and
# stderr.
\spawn =
(
### Use error-checking versions of system routines
\pipe =
(\next
pipe \status\read\write
long_lt status 0 (die "pipe failed");
next read write
)
 
\dup2 =
(\oldfd\newfd\next
dup2 oldfd newfd \status
long_lt status 0 (die "dup2 failed");
next
)
 
\fdopen =
(\fd\mode\next
fdopen fd mode next;
die "fdopen failed"
)
 
\fork =
(\next
fork \pid
long_lt pid 0 (die "fork failed");
next pid
)
 
# Now here's the spawn function itself.
\child_fn\next
# First flush the parent's stdout and stderr to avoid any pending output
# accidentally getting pushed into the child's input. I've noticed this
# can happen when your script output is sent to a file or pipe instead of
# a console.
get_stdout \fh fflush fh \_
get_stderr \fh fflush fh \_
# Now create a series of pipes, each with a read and write side.
pipe \r_in\w_in
pipe \r_out\w_out
pipe \r_err\w_err
 
fork \pid
long_eq pid 0
(
# Child process.
 
# Duplicate one side of each pipe into stdin, stdout, and stderr
# as appropriate.
dup2 r_in 0;
dup2 w_out 1;
dup2 w_err 2;
 
# Close unused file handles. They're all unused because we duped the
# ones we need. Also, we must close w_in or the child hangs waiting
# for stdin to close.
close r_in; close w_in;
close r_out; close w_out;
close r_err; close w_err;
 
# Now run the child function, which can use stdin, stdout, and stderr
# normally.
child_fn
)
(
# Parent process. Open the opposite side of each pipe into three new
# file handles.
fdopen w_in "w" \child_in
fdopen r_out "r" \child_out
fdopen r_err "r" \child_err
 
# Close unused file handles. We don't close the ones we fdopened
# because they are still in play (i.e. fdopen does not dup).
close r_in;
close w_out;
close w_err;
 
# Return the child's pid, stdin, stdout, and stderr.
next pid child_in child_out child_err
)
)
</lang>
 
<lang fexl>
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.