Try to search your question here, if you can't find : Ask Any Question Now ?

Unlimited piping in c from command line arguments

HomeCategory: stackoverflowUnlimited piping in c from command line arguments
Avatarkundan asked 3 months ago

I’m attempting to be able to emulate piping using c through command line arguments only not user input. What i have so far is a program that works solely through user input and i’m having difficulty understanding how to transfer the concatenated string of command line args to work the same as if a user had input these arguments at run time.

The only way my program seems to want to run these commands correctly is if i enter them in as user input otherwise i end up getting a segmentation fault and i’m not quite sure why that is.

Below is the functioning code with the user input method but also with the concatenated string above it that i would prefer to use so that the commands can be entered prior to run-time.

CODE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/wait.h>

static char* args[512];
pid_t pid;
int command_pipe[2];

#define READ  0
#define WRITE 1

static int command(int input, int first, int last)
{
    int pipettes[2];

    pipe( pipettes );   
    pid = fork();


    if (pid == 0) {
        if (first == 1 && last == 0 && input == 0) {
            // First command
            dup2( pipettes[WRITE], STDOUT_FILENO );
        } else if (first == 0 && last == 0 && input != 0) {
            // Middle command
            dup2(input, STDIN_FILENO);
            dup2(pipettes[WRITE], STDOUT_FILENO);
        } else {
            // Last command
            dup2( input, STDIN_FILENO );
        }

        if (execvp( args[0], args) == -1)
            _exit(EXIT_FAILURE); 
    }

    if (input != 0) 
        close(input);


    close(pipettes[WRITE]);


    if (last == 1)
        close(pipettes[READ]);

    return pipettes[READ];
}


static void cleanup(int n)
{
    int i;
    for (i = 0; i < n; ++i) 
        wait(NULL); 
}

static int run(char* cmd, int input, int first, int last);
static char line[1024];
static int n = 0; /* number of calls to 'command' */

int main(int argc, char *argv[])
{
    while (1) {

        for(int i = 1; i < argc; i++){
            strcat(line, argv[i]);
            strcat(line, " ");
        }

        /* Read a command line */
        if (!fgets(line, 1024, stdin)) 
            return 0;

        int input = 0;
        int first = 1;

        char* cmd = line;
        char* next = strchr(cmd, '@'); /* Find first '|' */

        while (next != NULL) {
            /* 'next' points to '|' */
            *next = '';
            input = run(cmd, input, first, 0);

            cmd = next + 1;
            next = strchr(cmd, '@'); /* Find next '|' */
            first = 0;
        }
        input = run(cmd, input, first, 1);
        cleanup(n);
        n = 0;
    }
    return 0;
}

static void split(char* cmd);

static int run(char* cmd, int input, int first, int last)
{
    split(cmd);
    if (args[0] != NULL) {
        if (strcmp(args[0], "exit") == 0) 
            exit(0);
        n += 1;
        return command(input, first, last);
    }
    return 0;
}

static char* skipwhite(char* s)
{
    while (isspace(*s)) ++s;
    return s;
}

static void split(char* cmd)
{
    cmd = skipwhite(cmd);
    char* next = strchr(cmd, ' ');
    int i = 0;

    while(next != NULL) {
        next[0] = '';
        args[i] = cmd;
        ++i;
        cmd = skipwhite(next + 1);
        next = strchr(cmd, ' ');
    }

    if (cmd[0] != '') {
        args[i] = cmd;
        next = strchr(cmd, 'n');
        next[0] = '';
        ++i; 
    }

    args[i] = NULL;
}
1 Answers
Best Answer
AvatarArben answered 3 months ago
Your Answer

10 + 16 =

Popular Tags

WP Facebook Auto Publish Powered By : XYZScripts.com