Question

pid_t childPid = fork ();
if (childPid == (pid_t) 0)//zero success
{
    const char *path = "/usr/local/mysql/bin/mysql";
    //doesn't work
    //char * const parmList[] = {"--user=root", "test_db", NULL};
    //does work
    char * const parmList[] = {"", "--user=root", "test_db", NULL};
    execv(path, parmList);
    printf("ERROR:\tFork failed.\n");   
}
else if (childPid < (pid_t) 0)// -1 failure
{
    /* The fork failed. */
    printf("ERROR:\tFork failed.\n");   
    return EXIT_FAILURE;
}
else
{
    while (true) {
        //stay alive
        sleep(1);
    }
}
printf("done");
exit(0);

I am having trouble importing a sql dump by using execv. You can see I wasn't able to login using the first paramList but the second one worked just fine. Anyways, if I add to the param list:

char * const parmList[] = {"", "--user=root", "test_db", "<", "/Users/joelsaltzman/Desktop/dump.sql", NULL};

The output shows the mysql help for the command line args like I typed something wrong. Does anybody know how to get this to work?

Was it helpful?

Solution

The first paramList is incorrect, because the first element should be the filename of the program you are going to execute:

The argument argv is an array of character pointers to null-terminated strings. The application shall ensure that the last member of this array is a null pointer. These strings shall constitute the argument list available to the new process image. The value in argv[0] should point to a filename that is associated with the process being started by one of the exec functions.

The input redirection with < does not work because this is not a feature of the kernel (which you invoke using execv), but of usual Unix shells. The system library call is what you are looking for. (It also just uses a call from the exec-family, but calls a shell with your command, which will then support <.)

Be sure to read the manpage system(3) and think about input validation if you are going to pass it a string that could be influenced by a malicious user.

OTHER TIPS

The second one works better, because the first parameter should be the command name. Therefore, MySQL starts reading from the second parameter. You should use the command name (the path), not an empty string, but it normally doesn't matter.

You can't use redirection with execv, because this is a shell feature, and execv doesn't run the shell. You can execute /bin/sh, with parameters that tell it to run mysql, or you can use dup2 to change stdin to whatever you want.

Use popen() instead to start mysql, and then write the contents of the sql file into the process yourself.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top