2012-02-11 2 views
0
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); 

execvを使用してSQLダンプをインポートする際に問題があります。私は最初のparamListを使ってログインすることができなかったが、2番目のparamListはうまくいきました。とにかく、私はのparamリストに追加した場合:私は何かを間違って入力したようexecvからmysql importを実行する

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

出力は、コマンドライン引数のためのmysqlのヘルプを示しています。 誰かがこれを動作させる方法を知っていますか?最初の要素は、あなたが実行しようとしているプログラムのファイル名でなければなりませんので

答えて

3

最初paramListは、間違っています:

引数のargvがNULLで終わる文字列への文字ポインタの配列です。アプリケーションは、この配列の最後のメンバーがヌルポインタであることを保証する。これらの文字列は、新しいプロセスイメージで使用可能な引数リストを構成します( )。 argv [0]の値は、exec関数の1つで起動されているプロセスに関連付けられているファイル名を指している必要があります。

これは(あなたがexecvを使用して呼び出す)カーネルのが、通常のUnixシェルの機能ではありませんので、<と入力のリダイレクトは動作しません。 systemライブラリコールがあなたが探しているものです。 (それはまたちょうど-family execからの呼び出しを使用していますが、その後<をサポートしますあなたのコマンドとシェルを呼び出します。)

はmanページsystem(3)を読んで、あなたが通過しようとしている場合、入力検証を考えるようにしてくださいそれは悪意のあるユーザーの影響を受ける文字列です。

+0

'mysql'プログラムに' --user = root'と言うのは合法ですが(しかし非常に奇妙ですが)、プログラムによってオプション引数として扱われません。また、空の文字列を指定することによってプログラムに何が呼び出されているかを伝えるのではなく、正当なものです(しかし、奇妙です)。これは、プログラムがその名前を見て、それが何をすべきかを決定する場合には重要です。これは、プログラムが呼び出された名前によって異なる動作をするように設計されている場合に発生します。 ( 'cc'と' gcc'は同じ実行可能ファイルへのリンクであり、 'c89'と' c99'は 'gcc'へのリンクではなく単純なスクリプトです)。 –

2

最初のパラメータはコマンド名である必要があるため、2番目の方がうまくいきます。したがって、MySQLは2番目のパラメータから読み込みを開始します。空の文字列ではなく、コマンド名(パス)を使用する必要がありますが、通常は問題ありません。

execvでリダイレクトを使用することはできません。これはシェル機能であり、execvはシェルを実行しないためです。 /bin/shを実行し、mysqlを実行するように指示するパラメータを使用するか、dup2を使用してstdinを任意の値に変更することができます。

1

代わりにpopen()を使用してmysqlを起動し、sqlファイルの内容をプロセスに書き込んでください。

関連する問題