Click here to Skip to main content
15,887,862 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to make a shell where the child process runs linux commands(with the help of execvp) such as "ls" etc.The problem is that i also want it to support pipe commands such as "ls /tmp | wc -l" .Τhe program i have for now works for commands like "ls" or "ls -l /tmp"
Posted
Updated 27-Nov-15 10:24am
v5
Comments
George Jonsson 24-Nov-15 19:19pm    
So what you want to do is to extract sub-strings separated by a | (pipe) character?
Member 12164719 24-Nov-15 19:49pm    
Yes,i want to tokenize a command input by the user and and using exec i want to execute it in the child process(exec takes as inputs the substrings(tokens)).If that command is "ls /tmp | wc -l" then it has to be executed normally just like it would from the parent.
Thanks for the reply

1 solution

For dup2 you can have a look here: dup2(2) - Linux man page[^]

For the code, start with an outer loop where you split the input string at the pipe character. Then create a function that takes care of the execution of the each command.
C++
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>

size_t TrimWhiteSpace(char *out, size_t len, const char *str);
void ExecuteCommand(const char* command);

int main()
{	
    char input[80] = "ls / tmp | wc - l";
    const char sep[2] = "|";
    char *token = NULL;
    char* command = NULL;
    
    token = strtok(input, sep);
    
    while (token != NULL)
    {
        command = (char*)calloc(strlen(token) + 1, sizeof(char));
        TrimWhiteSpace(command, strlen(token) + 1, token);
        
        printf("%s\n", command);
        
        ExecuteCommand(command);
        
        token = strtok(NULL, sep);
    }
    return 0;
}

size_t TrimWhiteSpace(char *out, size_t len, const char *str)
{
    if (len == 0)
    	return 0;
    
    const char *end;
    size_t out_size;
    
    // Trim leading space
    while (isspace(*str)) 
    	str++;
    
    if (*str == 0)  // All spaces?
    {
    	*out = 0;
    	return 1;
    }
    
    // Trim trailing space
    end = str + strlen(str) - 1;
    while (end > str && isspace(*end)) 
    	end--;
    end++;
    
    // Set output size to minimum of trimmed string length and buffer size minus 1
    out_size = (end - str) < len - 1 ? (end - str) : len - 1;
    
    // Copy trimmed string and add null terminator
    memcpy(out, str, out_size);
    out[out_size] = 0;
    
    return out_size;
}

void ExecuteCommand(const char* command)
{
    // Fork and execute your processes here
}


(The method TrimWhiteSpace, I found at StackOverflow: How do I trim leading/trailing whitespace in a standard way?[^])

This link might be interesting as well: Execute a Program: the execvp() System Call[^]
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900