Reputation: 31
I need to implement a basic shell in C. One of things I need is to implement a function that has a command and to execute it. my code:
pID=fork();
if (pID == 0)
execvp(tmp[0], tmp);
else if (pID > 0)
{
printf("%d", pID);
wait(NULL);
}
else
printf("Failed to create proccess \n");
The problem is that no matter what is the command I put in tmp, the program shows me the prompt again, and do nothing except that.
For example if I write gedit
(in order to open the gedit
— a ntpad of Ubuntu), it doesn't open it, or if write ls -a
it doesn't show me any output as the terminal of Ubuntu does.
Upvotes: 1
Views: 6759
Reputation: 1
execvp() requires full path . If in tmp[0] isnt the full path of your executable file use execv()
execv(tmp[0], tmp);
Upvotes: 0
Reputation: 400274
Although you've failed to tell us what you're passing through the tmp
variable to execvp
, my psychic sense tells me that you forgot to null-terminate your argument list. A NULL argument tells execvp
where the last argument is, and if you fail to put in a NULL, it will start reading random garbage off the stack.
If that random garbage points to large strings of non-zero data, it will run out of space to store the supposed arguments to the new process, which is typically a few hundred KB (see this page for some system-specific numbers, as well as various ways of getting your system's maximum arguments size).
When there's too much argument data, the system call execve(2)
(called internally by execvp
) fails with the error E2BIG
.
So to see if this is what's happening to you, check the return value from execvp
. If it even returns at all, it failed (if it succeeded, it wouldn't have returned since a new process would be executing!), so check the global value of errno
to see why it failed:
if (pID == 0)
{
execvp(tmp[0], tmp);
printf("exec failed: %s\n", strerror(errno));
exit(1);
}
Upvotes: 1
Reputation: 124
execvp should work. As the others mentioned, you really need to show how you populate tmp. That said, I would guess that that's where the error is. tmp needs to be a null terminated array.
#include <stdio.h>
main( int argc, char * argv[] )
{
int pid = fork;
char * tmp[2];
memset( tmp, 0, sizeof(tmp) );
tmp[0] = argv[0];
if( 0 == pid )
{
if( -1 == execvp( tmp[0], tmp ) )
{
char errmsg[64];
snprintf( errmsg, sizeof(errmsg), "exec '%s' failed", tmp[0] );
perror( errmsg );
}
else if( 0 < pid )
{
printf("[%d] %s\n", pid, tmp[0]);
wait(NULL);
}
else
{
perror("fork failed");
}
}
Upvotes: 2