Reputation: 23
I am trying to create a simple c program that takes user input, passes it to underlying shell and return the ouput of the user command. For eg: pwd will give the present working directory.
I want to do this using fork() and exec() in an infinite loop but I am facing two problems:
It only takes first argument. 'ls -ltr' will give me the output of 'ls' and not 'ls -ltr'
int runit(char*);
void main() {
int pid=0;
char command[50];
while(1)
{
int d=0;
printf("Please enter your command!\n");
scanf("%s", &command);
switch (pid = fork())
{
case 0: // a fork returns 0 to the child
printf("Child process \n");
d=runit(command);
if(d==-1){
printf("command not found \n");}
break;
default:
wait(5); // a fork returns a pid to the parent
printf("Parent process \n");
break;
case -1: //if something went wrong
perror("fork");
exit(1);
}
}
}
int runit(char* command) { //executing the command
char path[50]="/bin/";
int d = execl(strcat(path,command),command,NULL,NULL);
return(d);
}
Can somebody tell me what I am doing wrong or guide me how to correct this.
Upvotes: 2
Views: 243
Reputation: 121347
This input reading
scanf("%s", &command);
would stop at the first whitespace (unless input failure occurs -- you should check the return value of scanf()
in any case). So, when you input ls -ltr
, command
will have just ls
. You need to read lines. For example, use fgets()
to read input (and make sure to handle the trailing newline):
fgets(command, sizeof command, stdin);
command[strcspn(command, "\n")] = 0; /* to remove \n if present */
And the next problem is that execl()
takes multiple arguments. That means
this usage:
int d = execl(strcat(path,command),command,NULL,NULL);
is broken. You need to split the input command into multiple strings and pass each arguments to execl()
. A better option to store the individual strings in an array and use execv()
instead.
Another thing you need to be aware of is exec*()
family functions do not return on success. So, the return code check isn't very useful - instead you can just use perror()
to know why it failed if it failed.
Upvotes: 2