tags:

views:

500

answers:

5

How can I call awk or sed inside a c program? I know I could use exec(), but I don't want to deal with fork() and all that other nastiness.

+5  A: 

Then your choice is system(), or using some library that wraps process spawning for you. The latter, or the hard-core way you wanted to avoid, is recommended if you want fine control over errors, pipes, and so on.

unwind
+7  A: 

Would popen work? It spawns the process, then you read/write with a FILE* handle

eduffy
+2  A: 

system() is easy enough.

But you should try not to do this if you can. Scripts work best when they are on top of things, not underneath. If you're in UNIX, it's often way better to break up the work and write a top level script to call all of the pieces.

I remember watching a programmer add a huge number of system calls into his C code in order to avoid having to learn the Bourne shell. He figured it was a clever and quick way to get it going, however when it failed, it failed badly. He wasted huge amounts of time debugging the mess. It would have been way faster to just learn a few simple shell commands...

Paul.

Paul W Homer
+1  A: 

libc has functions system and popen, which work kinda like this:

int system(cont char *command) {
    const char *argv[4] = {"/bin/sh", "-c", command};
    int status;
    pid_t child = fork();
    if (child == 0) {
        execve(argv[0], argv, NULL);
        exit(-1);
    }
    waitpid(child, &status, 0);
    return status;
}

FILE *popen(const char *command, const char *type) {
    int fds[2];
    const char *argv[4] = {"/bin/sh", "-c", command};
    pipe(fds);
    if (fork() == 0) {
        close(fds[0]);
        dup2(type[0] == 'r' ? 0 : 1, fds[1]);
        close(fds[1]);
        execve(argv[0], argv, NULL);
        exit(-1);
    }
    close(fds[1]);
    return fdopen(fds[0], type);
}

(except with more error checking and stuff)

If you want finer control over argument handling (instead of going through sh), or you want control over more than one of {stdin, stdout, stderr}, you'll have to write it yourself or find a library. But the standard library covers most use cases.

ephemient
+1  A: 

You can do it via the system() call This Thread is a good example

TStamper