execv() not working properly

4.6k Views Asked by At

I am having a weird issue. For homework I am creating my own basic bash script, but when running execv() to run my cp command, it does not work. It works with ls and groups, but not cp. I messed around with my cp program to isolate the error and it is indeed the execv command.

void ls(char** array)
{
        pid_t pid = fork();
        if (pid == 0)
        {
                execv("./ls",array);
        }
        else
        {       
                waitpid(pid,0,0);
        }

}

void cp(char** array)
{
        pid_t pid = fork();
        if (pid == 0)
        {
                execv("./cp",array);
        }
        else
        {
                waitpid(pid,0,0);
        }
}

void groups(char** array)
{
        pid_t pid = fork();
        if (pid == 0)
        {
                execv("./groups",array);
        }
        else
        {
                waitpid(pid,0,0);
        }
}

int input()
{
        char buffer[128];
        char * str;
        char * str1;
        char * str2;
        char * str3;
        char *name;
        int i = 0;
        int num;
        int words = 1;
        name = getlogin();
        printf("%s --->", name);
        int result = scanf("%[^\n]",buffer);
        getchar();
        char **array;
        if (result > 0)
        {
                for (int i = 0; buffer[i]!='\0'; i++)
                {
                        if (buffer[i] == ' ' || buffer[i] == '\n' || buffer[i] == '\t')
                        {
                                words++;
                        }
                }

                array = malloc(words * sizeof(char*));
                array[0] = strtok(buffer, " ");
                for(int w = 1; w < words; w++)
                {
                        array[w] = strtok(NULL, " ");
                }
                if (words == 1)
                {
                        array[1] = '\0';
                }

        }
        str = strstr(array[0], "ls");
        str1 = strstr(array[0], "cp");
        str2 = strstr(array[0], "groups");
        str3 = strstr(array[0], "exit");
        if (str != NULL)
        {
                ls(array);
                free(array);
        }
        else if (str1 != NULL)
{
                cp(array);
                free(array);
        }
        else if (str2 != NULL)
        {
                groups(array);
                free(array);
        }
        else if (str3 != NULL)
        {
                num = 0;
                free(array);
                return num;
        }
        else
        {
                printf("Incorrect command\n");
        }
        num = 1;
        return num;

I feel that this snippet should be fine. My code gets to the execv correctly, it just doesn't execute it for some reason. ls and groups works fine, but cp does not. My main just calls input

2

There are 2 best solutions below

4
On

My guess based on the limited information is that the array that is sent as a parameter only contains one of the two things you would like to send to cp. Verify that you send both source and destination to cp by printing the array before calling execv. Also make sure that the arrays last element is a null pointer.

3
On

This works for me:

char* args[] = { "/bin/cp", "/etc/passwd", "passwd-copy", 0 };
pid_t pid; 
if(0>(pid=fork())){
    perror(0); 
    return -1;
}
if(0==pid){
    execv(args[0], args);
    perror(0);
    _exit(127);
}
siginfo_t info;
if(0>waitid(P_PID, pid, &info, WEXITED)){
    perror(0);
    return -1;
}
return info.si_status;