Help with simple linux shell implementation
        Posted  
        
            by nunos
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by nunos
        
        
        
        Published on 2010-04-15T17:39:40Z
        Indexed on 
            2010/04/15
            17:43 UTC
        
        
        Read the original article
        Hit count: 369
        
I am implementing a simple version of a linux shell in c.
I have succesfully written the parser, but I am having some trouble forking out the child process. However, I think the problem is due to arrays, pointers and such, because just started C with this project and am not still very knowledgable with them.
I am getting a segmentation fault and don't know where from. Any help is greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#define MAX_COMMAND_LENGTH 250
#define MAX_ARG_LENGTH 250
typedef enum {false, true} bool;
typedef struct {
    char **arg;     
    char *infile;   
    char *outfile;  
    int background; 
} Command_Info;
int parse_cmd(char *cmd_line, Command_Info *cmd_info)
{
    char *arg;
    char *args[MAX_ARG_LENGTH]; 
    int i = 0;
    arg = strtok(cmd_line, " ");
    while (arg != NULL) {
        args[i] = arg;
        arg = strtok(NULL, " ");
        i++;
    }
    int num_elems = i;
    if (num_elems == 0)
        return -1;
    cmd_info->infile = NULL;
    cmd_info->outfile = NULL;
    cmd_info->background = 0;
    int iarg = 0;
    for (i = 0; i < num_elems-1; i++)
    {                   
        if (!strcmp(args[i], "<"))
        {
            if (args[i+1] != NULL)
                cmd_info->infile = args[++i];
            else
                return -1;                      
        }
        else if (!strcmp(args[i], ">"))
        {
            if (args[i+1] != NULL)
                cmd_info->outfile = args[++i];
            else 
                return -1;                          
        }
        else
            cmd_info->arg[iarg++] = args[i];
    }
    if (!strcmp(args[i], "&"))
        cmd_info->background = true;
    else
        cmd_info->arg[iarg++] = args[i];
    cmd_info->arg[iarg] = NULL; 
    return 0;   
}
void print_cmd(Command_Info *cmd_info)
{
    int i;  
    for (i = 0; cmd_info->arg[i] != NULL; i++)
        printf("arg[%d]=\"%s\"\n", i, cmd_info->arg[i]);
    printf("arg[%d]=\"%s\"\n", i, cmd_info->arg[i]);    
    printf("infile=\"%s\"\n", cmd_info->infile);
    printf("outfile=\"%s\"\n", cmd_info->outfile);
    printf("background=\"%d\"\n", cmd_info->background);
}
void get_cmd(char* str)
{
    fgets(str, MAX_COMMAND_LENGTH, stdin);
    str[strlen(str)-1] = '\0'; //apaga o '\n' do fim
}
pid_t exec_simple(Command_Info *cmd_info)
{
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("Fork Error");
        return -1;
    }
    if (pid == 0)
    {
        execvp(cmd_info->arg[0], cmd_info->arg);
        perror(cmd_info->arg[0]);
        exit(1);
    }
    return pid;
}
int main(int argc, char* argv[])
{
    while (true)
    {
        char cmd_line[MAX_COMMAND_LENGTH];
        Command_Info cmd_info;
        printf(">>> ");
        get_cmd(cmd_line);
        if ( (parse_cmd(cmd_line, &cmd_info) == -1) )   
            return -1;
        parse_cmd(cmd_line, &cmd_info);
        if (!strcmp(cmd_info.arg[0], "exit"))
            exit(0);
        pid_t pid = exec_simple(&cmd_info);
        waitpid(pid, NULL, 0);  
    }
    return 0;
} 
Thanks.
© Stack Overflow or respective owner