I'm building a shell for bash in C , and I try to execute simple commands , but the output of the shell is not correct .
As for the moment it only supports the
>
feature , e.g writing to a file the output of the running program .
The code :
main()
code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
char errorStr[BUFF3];
while (1)
{
int i , errorFile , fd;
char ch;
char *line = malloc(BUFFER);
char *origLine = line;
// fgets(line, BUFFER, stdin); // get a line from stdin . ls Debug > t.ourr
scanf("%[^\n]",line); // ls Debug > dir.out
scanf("%c",&ch);
// get complete diagnostics on the given string
lineData info = runDiagnostics(line);
char command[20];
sscanf(line, "%20s ", command);
printf("The Command is: %s\n", command);
int currentCount = 0; // number of elements in the line
int *argumentsCount = ¤tCount; // pointer to that
// get the elements separated
char** arguments = separateLineGetElements(line,argumentsCount);
executeCommand(info , line , arguments , argumentsCount);
|
And auxiliary methods :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
void runGreaterThan(char* command , char** arguments , int numberOfArguments)
{
int i = 0 ;
int errorFile = 0, fd;
char errorStr[BUFF3];
char * fileName = arguments[numberOfArguments - 1];
fd = open(fileName,O_WRONLY | O_TRUNC | O_CREAT,0600);
if (fd < 0)
{
perror("open failed\n");
exit(0);
}
pid_t pid ;
if (-1 == (pid = fork())) // fork failed
{
sprintf(errorStr,"fork: %s\n",strerror(errno));
write(errorFile,errorStr,strlen(errorStr + 1));
perror("fork");
exit(1);
}
else if (0 == pid) // fork was successful
{
printf("\nIn son process\n");
dup2(fd, STDOUT_FILENO);
close(fd);
if (execvp(command,arguments) < 0) // execute the command
{
perror("execvp");
printf("ERROR: execvp failed\n");
exit(1);
}
}
else // parent
{
int status = 0;
pid = wait(&status);
printf("Process %d returned with status %d.\n", pid, status);
}
}
|
and
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
void executeCommand(lineData info , char* wholeLine , char ** arguments , int * argumentsCount)
{
int totalPipes = info.numberPipes; // use this for knowing how much pipes we'd have
int i = 0 , j = 0; // use this to run on the whole string
char* command = NULL; // here we store the command
char ** args = (char**)malloc(4 * sizeof(char*)); // create 4 cell for now
int iterator = 0; // using this to iterate the separated arguments
// running on all the line , even if we have 0 zero pipes
int currectCommandCount = 0;
while (iterator <= totalPipes)
{
int argCount = *argumentsCount;
while (i < argCount && (strcmp(arguments[i], "|\0") != 0) )
{
if (i == 0)
command = arguments[i];
else if (strcmp(arguments[i] , ">\0") != 0) // meaning - don't put the > sign in the arguments
{
currectCommandCount++;
args[j] = (char*) malloc(strlen(arguments[i]) * sizeof(char));
strcpy (args[j] , arguments[i]);
j++;
}
i++;
}
// here we execute the current command & its args & its counter of args
runGreaterThan(command , args , currectCommandCount);
iterator++;
}
}
|
The problem : when I execute the command
ls Debug/ > q.out
all I get is a the file with its name appearing in it ,
but without the contents of the folder
Debug
.
I suspect that there is something wrong with my
execvp()
function .
Any idea how to fix this ? I've tried to make this work for the past two days ,but nothing .
Update : Eclipse thinks that for
ls > r.out
, the
>
is a library (folder) , so I get
as the output :
cannot access >: No such file or directory . How can I fix this ?
Best Regards
David