2

新しいプロセスを作成するプログラムを作成したいのですが、その子プロセスで次のコマンドを実行する必要がありますls。その間、親は子供が死ぬのを待つ必要があります。しかし、私のコードは機能しません。

どうもありがとうございました!

int main()
{
    char * read;
    size_t size;

    getline(&read , &size , stdin);
    read[strlen(read)-1] = '\0';
    printf("%s\n" , read);
    int status;
    pid_t f;
    if((f = fork()) == 0)   
    {
        execvp(read , &read);
        exit(0);
    }
    else
    {   
        wait(&status);
    }       
}
4

3 に答える 3

3

man execvpから:

execv()、execvp()、および execvpe() 関数は、新しいプログラムで使用可能な引数リストを表すヌル終了ストリングへのポインターの配列を提供します。最初の引数は、慣例により、実行中のファイルに関連付けられたファイル名を指す必要があります。ポインターの配列は、NULL ポインターで終了する必要があります。

char*の配列を使用し、最後の要素を に設定する必要がありますNULL

が何を読んでいるのかはわかりませんが、 dgetline()されるディレクトリだと思います。lsの最初の引数execvp()は でls、2 番目の引数は の配列ですchar*

于 2012-09-27T16:38:30.083 に答える
1

次の点を考慮してください。

#define  _GNU_SOURCE
#define  _POSIX_C_SOURCE 200809L

#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    char   *input_arg[2];
    char   *input_str = NULL;
    size_t  input_len = 0;
    char  **args;
    ssize_t len;
    size_t  n;
    pid_t   child, p;
    int     status;

    if (argc < 2) {

        /* No command line parameters. Read command from stdin. */
        len = getline(&input_str, &input_len, stdin);

        /* Find length excluding the newline at end. */
        if (len > (ssize_t)0)
            n = strcspn(input_str, "\r\n");
        else
            n = 0;

        if (n > (size_t)0) {

            /* Terminate input command before the newline. */
            input_str[n] = '\0';

        } else {

            fprintf(stderr, "No input, no command.\n");
            return 1;
        }

        input_arg[0] = input_str;
        input_arg[1] = NULL;
        args = input_arg;

    } else {

        /* Use command line parameters */
        argv[argc] = NULL;
        args = argv + 1;
    }

    child = fork();
    if (child == (pid_t)-1) {
        fprintf(stderr, "Cannot fork: %s.\n", strerror(errno));
        return 1;
    }

    if (!child) {
        /* This is the child process. */

        errno = ENOENT;
        execvp(args[0], args);

        fprintf(stderr, "%s: %s.\n", args[0], strerror(errno));
        exit(127);
    }

    do {
        p = waitpid(child, &status, 0);
    } while (p == (pid_t)-1 && errno == EINTR);
    if (p == (pid_t)-1) {
        fprintf(stderr, "Lost child process: %s.\n", strerror(errno));
        return 127;

    }
    if (p != child) {
        fprintf(stderr, "waitpid() library bug occurred.\n");
        return 127;

    }

    if (WIFEXITED(status)) {
       if (!WEXITSTATUS(status))
           fprintf(stderr, "Command successful.\n");
       else
           fprintf(stderr, "Command failed with exit status %d.\n", WEXITSTATUS(status));
       return WEXITSTATUS(status);
    }

    if (WIFSIGNALED(status)) {
        fprintf(stderr, "Command died by signal %s.\n", strsignal(WTERMSIG(status)));
        return 126;
    }

    fprintf(stderr, "Command died from unknown causes.\n");
    return 125;
}

上記は、指定されている場合はコマンド ライン パラメータを使用し、それ以外の場合は標準入力から 1 つ読み取ります。標準入力はトークン化されていないため、コマンド名のみを指定でき、パラメーターは指定できません。input_arg[]配列を拡大すると

    char   *input_arg[4];

割り当てを次のように変更します

    input_arg[0] = "/bin/sh";
    input_arg[1] = "-c";
    input_arg[2] = input_str;
    input_arg[3] = NULL;
    args = input_arg;

入力文字列は、/bin/shシェルを使用して処理されますpopen()

割り当てを使用len = getdelim(&input_str, &input_len, '\0', stdin);および削除して、複数行の入力を許可することもできます。input_str[n] = '\0';コマンドライン引数バッファーに収まるほど短い限り、シェルはそれらをうまく処理する必要があります (最大長は OS によって異なります)。

シェルが入力を個別のコマンドとパラメーターに分割する方法のルールはかなり複雑であり、それらをエミュレートしようとするべきではありません。代わりに、ユーザーがパラメーターを個別に指定する簡単な方法 (コマンド ライン パラメーター ケースなど) を見つけるか、シェルを使用してそれを実行してください。分割を行わない場合は、おそらく入力行の末尾にある改行を削除する必要があります。

注意すべき点は、 forはexecvp(file, args)args[0]アプリケーションが ($0またはとしてargv[0])見る名前でargs[1]あり、最初のパラメーターであるということです。\0各パラメータは、通常 C の文字列と同じように NUL ( ) で終了し、argsポインタ配列はポインタで終了する必要がありNULLます。パラメータがない場合は、args[1] == NULL.

于 2012-09-27T23:19:06.057 に答える
0

システムコマンドを使用しないのはなぜですか...

#include <stdio.h>
#include <stdlib.h>


int main ()
{
  int i;
  printf ("Executing command ls...\n");
  i=system ("ls");
  printf ("The value returned was: %d.\n",i);
  return 0;
}

アップデート:

#include  <stdio.h>
#include  <sys/types.h>
#include <stdlib.h>

void  main(void)
{
     pid_t  pid;

     pid = fork();
     if (pid == 0) // this is child process
     {
      int i;
      printf ("Executing command ls...\n");
      i=system ("ls");
      printf ("The value returned was: %d.\n",i);
     }
     else // this is paraent process 
     {
      int status=0
      wait(&status);
      printf ("Child process is returned with: %d.\n",status);
      }
}
于 2012-09-27T16:30:50.970 に答える