Execute an arbitrary program as a child process? - Unix
This is a discussion on Execute an arbitrary program as a child process? - Unix ; There are a lot of sophisticated, high-quality programs out there,
and the system() call allows us access to their functionality.
Saves a lot of reinventing the wheel. But it's a blocking call,
and even if it weren't, there's no way ...
-
Execute an arbitrary program as a child process?
There are a lot of sophisticated, high-quality programs out there,
and the system() call allows us access to their functionality.
Saves a lot of reinventing the wheel. But it's a blocking call,
and even if it weren't, there's no way I know of to communicate
with the executed program.
I'm looking for a way to execute an arbitrary program and watch
its stdout and sdterr output. I've looked at of using fork(),
exec() and pthreads to start a process which will execute the
program and return, but I just can't see any way of getting
the executed program's PID or seeing its output.
(Well, I do see a possibility to redirect its output to a file
and read that, but that seems to me a very untidy hack, with
portability problems, and it doesn't allow me to send signals
to the program.)
Can anyone help?
-
Re: Execute an arbitrary program as a child process?
* Archer
| I'm looking for a way to execute an arbitrary program and watch its
| stdout and sdterr output. I've looked at of using fork(), exec() and
| pthreads to start a process which will execute the program and
| return, but I just can't see any way of getting the executed
| program's PID or seeing its output.
Have a look at popen(3) and/or pipe(2), the latter in combination with
fork/exec. There is some example code for pipe/fork/exec in Stevens'
code samples (links at http://www.kohala.com/start/apue.html).
If you show some code you've written, you will get better answers...
HTH
R'
-
Re: Execute an arbitrary program as a child process?
On 2008-02-04, Ralf Fassel wrote:
> * Archer
> | I'm looking for a way to execute an arbitrary program and watch its
> | stdout and sdterr output. I've looked at of using fork(), exec() and
> | pthreads to start a process which will execute the program and
> | return, but I just can't see any way of getting the executed
> | program's PID or seeing its output.
>
> Have a look at popen(3) and/or pipe(2), the latter in combination with
> fork/exec. There is some example code for pipe/fork/exec in Stevens'
> code samples (links at http://www.kohala.com/start/apue.html).
OMG! I've got that book on my shelf.
Ugh. Consider me chatised, please.
> If you show some code you've written, you will get better answers...
Haven't written any yet. It's a project in the planning stage.
I'll be writing in C++. The aim is to process sound files which
will be created by cdparanoia and audacity, converted from wav
to mp3 by lame and played by play (wav) or madplay (mp3), all
of that being done from the planned program.
It'll be a gui, for waveform display purposes, and I want to
catch both stdout and stderr from cdparanoia and madplay, and
stderr from lame. I'm learning Qt for the gui part.
As for play and audacity, they'll be fine with simple system()
calls.
Thanks for the link, Ralf. Much appreciated.
-
Re: Execute an arbitrary program as a child process?
Archer wrote:
# There are a lot of sophisticated, high-quality programs out there,
# and the system() call allows us access to their functionality.
# Saves a lot of reinventing the wheel. But it's a blocking call,
# and even if it weren't, there's no way I know of to communicate
# with the executed program.
#
# I'm looking for a way to execute an arbitrary program and watch
# its stdout and sdterr output. I've looked at of using fork(),
# exec() and pthreads to start a process which will execute the
# program and return, but I just can't see any way of getting
# the executed program's PID or seeing its output.
Use pipe() to create pipes that will replace stdin, stdout,
and stderr.
int pid = fork()
if (pid==0)
you are the child process
dup pipes to replace various fds 0, 1, 2
close the original pipe fds
set up any other aspect of the execution environment
exec the new program
if (pid>0)
you are the parent and pid is the child
close unused ends of pipes
write to child's stdin
and read from child's stdout and stderr
close pipes on eof
wait for child status
You have to child pid for a kill call.
If you have two or more pipes with blocking I/O in the same
thread, you are risking deadlock unless you're very careful
how you read and write. Alternatively each pipe has it own
thread, or do non-blocking I/O, possibly with select().
# (Well, I do see a possibility to redirect its output to a file
# and read that, but that seems to me a very untidy hack, with
/tmp is intended for temporary files. Those you forget to unlink
are removed on the next reboot.
--
SM Ryan http://www.rawbw.com/~wyrmwif/
If you plan to shoplift, let us know.
Thanks
-
Re: Execute an arbitrary program as a child process?
On Feb 4, 12:13 am, Archer wrote:
> I'm looking for a way to execute an arbitrary program and watch
> its stdout and sdterr output. I've looked at of using fork(),
> exec() and pthreads to start a process which will execute the
> program and return, but I just can't see any way of getting
> the executed program's PID or seeing its output.
Look at the "expect" tool which does all of this stuff and whose
source code is widely available.
DS
-
Re: Execute an arbitrary program as a child process?
SM Ryan wrote:
> Archer wrote:
----snip----
> # I'm looking for a way to execute an arbitrary program and watch
> # its stdout and sdterr output. I've looked at of using fork(),
> # exec() and pthreads to start a process which will execute the
> # program and return, but I just can't see any way of getting
> # the executed program's PID or seeing its output.
>
> Use pipe() to create pipes that will replace stdin, stdout,
> and stderr.
>
> int pid = fork()
>
> if (pid==0)
> you are the child process
> dup pipes to replace various fds 0, 1, 2
> close the original pipe fds
> set up any other aspect of the execution environment
> exec the new program
> if (pid>0)
> you are the parent and pid is the child
> close unused ends of pipes
> write to child's stdin
> and read from child's stdout and stderr
> close pipes on eof
> wait for child status
Ah. Nice and clean. Mille gracias.
> You have to child pid for a kill call.
I don't understand that. Are you saying that I have [a] child
pid for a kill all?
> If you have two or more pipes with blocking I/O in the same
> thread, you are risking deadlock unless you're very careful
> how you read and write. Alternatively each pipe has it own
> thread, or do non-blocking I/O, possibly with select().
As with watching both stderr and sdtout?
> # (Well, I do see a possibility to redirect its output to a file
> # and read that, but that seems to me a very untidy hack, with
>
> /tmp is intended for temporary files. Those you forget to unlink
> are removed on the next reboot.
I will be using files for input to play and madplay, but I'll
be using /dev/shm for that (and for audacity's tmp files too),
and deleting them after use (and umounting /dev/shm on exit).
That reminds me: what test can I install to choose /tmp for
users who aren't in /etc/sudoers for mount and umount?
-
Re: Execute an arbitrary program as a child process?
On 2008-02-05, David Schwartz wrote:
> On Feb 4, 12:13 am, Archer wrote:
> >
> > I'm looking for a way to execute an arbitrary program and watch
> > its stdout and sdterr output. I've looked at of using fork(),
> > exec() and pthreads to start a process which will execute the
> > program and return, but I just can't see any way of getting
> > the executed program's PID or seeing its output.
>
> Look at the "expect" tool which does all of this stuff and whose
> source code is widely available.
YAGI (yet another good idea).
My ignorance is obviously much greater than I knew.
Thanks, David.
-
Re: Execute an arbitrary program as a child process?
# > int pid = fork()
# > You have to child pid for a kill call.
#
# I don't understand that. Are you saying that I have [a] child
# pid for a kill all?
If you want to send a signal to the child, you have its pid,
kill(pid,SIGUSR1);
# > If you have two or more pipes with blocking I/O in the same
# > thread, you are risking deadlock unless you're very careful
# > how you read and write. Alternatively each pipe has it own
# > thread, or do non-blocking I/O, possibly with select().
#
# As with watching both stderr and sdtout?
Yes. The child might be blocked writing its stderr and you're
blocked reading its stdout. Neither process can proceed. There
a variety of solutions, but if you naively do nothing, it
will likely fail.
--
SM Ryan http://www.rawbw.com/~wyrmwif/
If your job was as meaningless as theirs, wouldn't you go crazy too?
-
Re: Execute an arbitrary program as a child process?
SM Ryan wrote:
> # >
> # > int pid = fork()
>
> ...
>
> # > You have to child pid for a kill call.
> #
> # I don't understand that. Are you saying that I have [a] child
> # pid for a kill all?
>
> If you want to send a signal to the child, you have its pid,
> kill(pid,SIGUSR1);
Had to check. I presume your original sentence contains a typo.
> # > If you have two or more pipes with blocking I/O in the same
> # > thread, you are risking deadlock unless you're very careful
> # > how you read and write. Alternatively each pipe has it own
> # > thread, or do non-blocking I/O, possibly with select().
> #
> # As with watching both stderr and sdtout?
>
> Yes. The child might be blocked writing its stderr and you're
> blocked reading its stdout. Neither process can proceed. There
> a variety of solutions, but if you naively do nothing, it
> will likely fail.
Danke schoen, RM.