Complete.Org: Mailing Lists: Archives: discussion: June 2000:
[aclug-L] Re: Programming questions
Home

[aclug-L] Re: Programming questions

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: discussion@xxxxxxxxx
Subject: [aclug-L] Re: Programming questions
From: Tom Hull <thull@xxxxxxxxxxx>
Date: Sun, 25 Jun 2000 23:47:23 -0500
Reply-to: discussion@xxxxxxxxx

james l wrote:
> 
> After staying late, and not having redhat's network installs work, until the
> 5th or so try. I decided to make a linux installer that will install a
> ssh-based xterm (basically) on a computer using a parport zip drive. But I am
> running into some problems.
> 
> I need to know how to exec another program from inside a c (or c++) program.
> (to start rpm, and some other programs/scripts) All of my other programming
> has been stand alone stuff and I cant find how to do it.

system(3) takes a single string argument, which is then passed to a shell as
in: /bin/sh -c 'command'. Example:

    system("who am i");

The program which you run inherits your stdin/stdout/stderr. You can include
shell redirection commands as part of the string. Your program waits for the
shell to return. You can include "&" as part of the string if you want it to
run in background. Beware, however, that it shares your stdin unless you
arrange otherwise.

The return value is a struct wait disguised as an integer. See 
/usr/include/sys/wait.h
for gory details. Most likely, all you're really interested in is whether the
command returned success (0) or failure (not-0), which you can figure out by
testing whether the return value is 0 or not. To find out exactly what the
return value is, whether it died due to a signal, etc., you need to use the
macros in <sys/wait.h>.

popen(3) also runs a shell command, except it returns a FILE* so you can
either write to the command's stdin or read from the command's stdout. (Newer
versions can do both, but your programs have to be very well behaved not to
get confused and deadlock.)

These are both library functions, which are convenient and somewhat limited.
The lower level system calls are fork(2), exec(2), pipe(2), wait(2). Roughly
speaking, you want to do something like:

    pid_t pid, retpid;
    int sts;

    pid = fork();
    if (pid == -1) {
        fprintf(stderr, "cannot fork [%s]\n", strerror(errno));
        exit(1);
    }
    if (pid == 0) {
        /* this is the child process. you can at this point do things like
         * redirect stdin/stdout/stderr. then, finally, exec your program:
         */
        execv(argv[0], argv);
        fprintf(stderr, "cannot exec [%s]\n", strerror(errno));
        exit(1);
    }
    while ((retpid = wait(&sts)) != pid && retpid != -1)
        ;

There are several choices for exec(2), depending on how you want to pass
the program name and arguments: execv() is the easiest. You can choose
not to wait at this time; you can use waitpid(2). You can do lots of things.

BTW: If you just call execv() or another exec(2) function, your program as
you know it is replaced by the new program, using your same process id.
This is also what happens with the shell exec command. You can do this
to chain together two program, such as when login execs your shell.

> Thanks,
> 
> James L
> 
> -- This is the discussion@xxxxxxxxx list.  To unsubscribe,
> visit http://tmp2.complete.org/cgi-bin/listargate-aclug.cgi

-- 
/*
 *  Tom Hull * thull@xxxxxxxxxxx * http://www.ocston.org/~thull/
 */

-- This is the discussion@xxxxxxxxx list.  To unsubscribe,
visit http://tmp2.complete.org/cgi-bin/listargate-aclug.cgi


[Prev in Thread] Current Thread [Next in Thread]