简体   繁体   中英

Trying to use execvp to execute external commands in C (in a shell like program)

so I had to implement support for executing external commands(for linux in the C programming language). This is what I have so far, I used the readline library for the history functions but that is irrelevant... can someone tell me what am I doing wrong? (I think it's the way I call "execvp") So here is my code:

#include<fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> 
#include <readline/readline.h>
#include <readline/history.h>
#define BUFFER_SIZE 256
#define READFILE_SIZE 4096

char ** parseCMD( char * );
void  EXEC(char *, char *);

int main(int argc, char ** argv)
{
    char  myPrompt[]= {'>', '_', '\0'};
    char *currLine = (char* ) malloc(sizeof(char) * BUFFER_SIZE),
                 *command = (char* ) malloc(sizeof(char) * BUFFER_SIZE),
                            *argument = (char* ) malloc(sizeof(char) * BUFFER_SIZE);

    currLine = readline(myPrompt);
    while((strcmp(currLine, "exit") != 0))
    {
        command = strtok(currLine, " ");
        argument = strtok( NULL, "");
        EXEC(command, argument);
        currLine = readline(myPrompt);
    }
return 0;
}

char ** parseCMD( char * buff )
{
    int i = 0, n = strlen(buff), j, count = 0;
    char ** CMDargs = (char **) malloc( sizeof( char ) * 100 * 100);
    if( buff == NULL )
        return NULL;
    for(i; i < n; i ++)
    {
        j = 0;
        char * aux = (char *) malloc( sizeof( char ) * 100);
        while( buff[i] != ' ' || buff[i] != '\t' || buff[i] != '\n')
        aux[j++] = buff[i++];
        aux[j] = '\0';
        CMDargs[count] = strdup( aux );
        count++;
        //printf("Argument %d is: %s", count - 1, CMDargs[count - 1]);
        free(aux);
    }
CMDargs[ count ] = NULL;
return CMDargs;
}

void  EXEC(char *command, char *argBuffer)
{
    pid_t  pid;
    int status, fd[2], n;
    char s[255];
    char ** Args;
    pipe( fd );
    Args = parseCMD( argBuffer );
    if ((pid = fork()) < 0)
    {
        printf("ERROR: forking child process failed\n");
        exit(1);
    }
    else if (pid == 0)
    {
        close(fd[0]);
        dup2(fd[1],1);
        if (execvp(command, Args) < 0)
        {
            printf("ERROR: execvp call failed\n");
            exit(1);
        }
        close(fd[1]);
    }
    else
    {
        close(fd[1]);
        while( ( n = read( fd[0], s, 255 ) ) > 0 )
        {
            s[n] = '\0';
            printf("%s",s);

        }
        while (wait(&status) != pid);
        close(fd[0]);
    }
}

There are just too many bugs in this, ask yourself, what will happen when I enter empty command (variable command is NULL and you will get segfault later on), what will hapen if I enter command without parameters (variable argument is NULL and you will get segfault later on), what will happend if I enter command with parameters? (while cycle in function parseCMD will never terminate and eventually you will access something that you shouldn't). Maybe time for you to learn using debugger. Try to step the program line by line and observe what is happening.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM