1

I am trying to implement my own shell. I have a few questions about my code and about tasks to resolve. Below I present my previous code and questions:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

void parse(char *line, char **argv, char **argv2)
{
    while (*line != '\0')
    {
        while (*line == ' ' || *line == '\t' || *line == '\n')
        {
            *line++ = '\0';
        }   

        if(*line == '>' && *(line+1) == '>')
        {
            while (*line != '\0' && *line != ' ' &&  *line != '\t' && *line != '\n')
            {
                line++;
            }           
            while (*line == ' ' || *line == '\t' || *line == '\n')
            {           
                *line++ = '\0';
            }
            *argv2 = line;
            break;
        }

        if(*line == '&')
        {
            break;
        }

        *argv++ = line;

        while (*line != '\0' && *line != ' ' &&  *line != '\t' && *line != '\n')
        {
            line++;
        }   
    }
    *argv = '\0';
}

void execute(char **argv, int option)
{
    pid_t pid;
    int status;

    if ((pid = fork()) < 0)
    {
        printf("*** ERROR ***\n");
        exit(1);
    }
    else if (pid == 0)
    {
        if (execvp(*argv, argv) < 0)
        {
            printf("*** ERROR ***\n");
            exit(1);
        }
    }
    else if(option == 1)
    {
        while (wait(&status) != pid);
    }
}

void execute2(char *command, char **argv, char **argv2)
{
    pid_t pid;
    int status;

    if ((pid = fork()) < 0)
    {
        printf("*** ERROR ***\n");
        exit(1);
    }
    else if (pid == 0)
    {
        //close(1);
        parse(command, argv, argv2);
        int output = open(*argv2, O_APPEND | O_WRONLY);
        dup2(output,1);
        if (strcmp(argv[0], "exit") == 0)
            exit(0);
        if (execvp(*argv, argv) < 0)
        {
            printf("*** ERROR ***\n");
            exit(1);
        }
        close(output);
    }
    else
    {
        while (wait(&status) != pid);
    }
}

int specialChar(char *argv)
{
    int i=0;
    while(argv[i]!='\0')
    {
        if(argv[i]=='>' && argv[i+1]=='>')
            return 1;           
        else if(argv[i]=='&')
            return 2;           
        else if(argv[i]=='|')
            return 3;           
        i++;
    }
}

void  main()
{
    char command[20];
    char *argv[64];
    char *argv2[1];
    char **history = (char**)malloc(20*sizeof(char*));
    int counterHistory1=-1;
    int counterHistory2=0;
    int i;

    for(counterHistory2 = 0; counterHistory2<20; counterHistory2++)
    {
        history[counterHistory2]=(char*)malloc(100*sizeof(char));
    }

    FILE *file;
    file=fopen("history", "w");
    if(!file)
        printf("ERROR");

    while (1)
    {
        printf("Shell -> ");
        gets(command);

        counterHistory1++;
        strcpy(history[counterHistory1],command);
        fopen("history", "w");
        if(counterHistory1<20)
            for(i=0; i<=counterHistory1; i++)
            {
                fprintf(file,"%s\n",history[i]);
            }
        else
            for(i=counterHistory1-20; i<counterHistory1; i++)
            {
                fprintf(file,"%s\n",history[i]);
            }

        fflush(file);
        printf("\n");

        switch(specialChar(command))
        {
            case 1:
                //close(1);
                execute2(command,argv,argv2);
            break;

            case 2:                                //running program in background
                parse(command, argv, argv2);
                if (strcmp(argv[0], "exit") == 0)
                    exit(0);
                execute(argv,0);
            break;

            case 3:

            break;

            default:
                parse(command, argv, argv2);
                if (strcmp(argv[0], "exit") == 0)
                    exit(0);
                execute(argv,1);
            break;
        }
        fclose(file);
        }
}
  1. When last sign getting from user is '&', I need to run my program in background. I have read that I can do this if I don 't call wait. Did I do this good or I should change something?
  2. In my shell I should create pipes of any length with the | sign. I have no idea how to resolve that problem.

closed as off-topic by Rui F Ribeiro, Jeff Schaller, Eric Renouf, Archemar, thrig Apr 22 '17 at 14:07

  • This question does not appear to be about Unix or Linux within the scope defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • It is a Linux C source in the question. What the heck wouldn't it be about Unix/Linux??? – peterh Apr 22 '17 at 19:56
  • Break your question into smaller ones, and try to make it look as if it wouldn't be about programming. This site essentially forbids programming questions while it doesn't admit it openly, but it will be okay until it is not obvious from them that they are about programming. – peterh Apr 22 '17 at 19:59

Browse other questions tagged or ask your own question.