-1

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]);
    }
}
Theo
  • 1
  • 1
  • 1
    So what's the problem? What expected behaviour is not occurring? – chrisaycock Nov 27 '12 at 18:23
  • I bet something is wrong with the parameters (strings) you pass to execvp. Try to print them out before calling execvp. – piokuc Nov 27 '12 at 18:24
  • I tried that... I did different prints and the arguments look ok... and I get seg fault for any command I enter now i.e "ls -la" – Theo Nov 27 '12 at 18:41

1 Answers1

1

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.

Miroslav Franc
  • 1,282
  • 12
  • 13