2016-05-16 13 views
-1

私は基本的なシェルのようなものを持っています。 私の問題は、私が./test ls -lのようなことをするときに-l引数を使用しないことです。 私が./test lsを行ったのとまったく同じです。男、int execvp(const char * file、char * const argv [])によると、** execvpは** argv全体を読むように強制されていませんか?execvpがargv []全体を読み取っていませんか?

int mySystem(char* str[]){ 
    wordexp_t p; 
    char **w; 
    wordexp(str[1],&p,0); 
    w = p.we_wordv; 
    int q= fork(); 
    if(q==0){ 
     execvp(w[0],w); 
     perror("erro"); 
     _exit(-1); 
    } 

    int sp; 
    wordfree(&p); 
    wait(&sp); 
    if(WIFEXITED(sp)){ 
     return WEXITSTATUS(sp); 
    } 
    return 0; 
} 

int main(int argc,char **argv){ 
    mySystem(argv); 
    return 0; 
} 

ありがとうございます。

+0

argv引数に期待される内容があることを確認しましたか?それとも、正しく設定したと仮定していますか? – rici

+0

p.we_wordv引数をループして印刷すると、指摘したようにlsを渡すだけです...問題はwordexp(str [1])の第1引数であると仮定していますか? – ohiohai

+0

なぜ厳密にwordexpを呼びますか? – rici

答えて

0

あなたの引数は(何も引用符がないこと末尾の0を注意して)次のようになります

static char *cmd[] = { "ls", "-l", 0 };

だからあなたはexecし、それが動作することを確認するために電話をしようとすると、ハードコーディングすることができます。

コードが完全ではないため、デバッグできません。デバッガを使用する場合は、値を検査できます。 argsはexecの配列になければならないことに注意してください。ここでは基本的なコードがあり、それを説明し、パイプラインを作ることを認めています。

/* One way to create a pipeline of N processes */ 

/* stderr.h */ 
#ifndef STDERR_H_INCLUDED 
#define STDERR_H_INCLUDED 

static void err_setarg0(const char *argv0); 
static void err_sysexit(char const *fmt, ...); 
static void err_syswarn(char const *fmt, ...); 

#endif /* STDERR_H_INCLUDED */ 

/* pipeline.c */ 
#include <assert.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/wait.h> 
#include <unistd.h> 
/*#include "stderr.h"*/ 

typedef int Pipe[2]; 

/* exec_nth_command() and exec_pipe_command() are mutually recursive */ 
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output); 

/* With the standard output plumbing sorted, execute Nth command */ 
static void exec_nth_command(int ncmds, char ***cmds) 
{ 
    assert(ncmds >= 1); 
    if (ncmds > 1) 
    { 
     pid_t pid; 
     Pipe input; 
     if (pipe(input) != 0) 
      err_sysexit("Failed to create pipe"); 
     if ((pid = fork()) < 0) 
      err_sysexit("Failed to fork"); 
     if (pid == 0) 
     { 
      /* Child */ 
      exec_pipe_command(ncmds-1, cmds, input); 
     } 
     /* Fix standard input to read end of pipe */ 
     dup2(input[0], 0); 
     close(input[0]); 
     close(input[1]); 
    } 
    execvp(cmds[ncmds-1][0], cmds[ncmds-1]); 
    err_sysexit("Failed to exec %s", cmds[ncmds-1][0]); 
    /*NOTREACHED*/ 
} 

/* Given pipe, plumb it to standard output, then execute Nth command */ 
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output) 
{ 
    assert(ncmds >= 1); 
    /* Fix stdout to write end of pipe */ 
    dup2(output[1], 1); 
    close(output[0]); 
    close(output[1]); 
    exec_nth_command(ncmds, cmds); 
} 

/* Execute the N commands in the pipeline */ 
static void exec_pipeline(int ncmds, char ***cmds) 
{ 
    assert(ncmds >= 1); 
    pid_t pid; 
    if ((pid = fork()) < 0) 
     err_syswarn("Failed to fork"); 
    if (pid != 0) 
     return; 
    exec_nth_command(ncmds, cmds); 
} 

/* Collect dead children until there are none left */ 
static void corpse_collector(void) 
{ 
    pid_t parent = getpid(); 
    pid_t corpse; 
    int status; 
    while ((corpse = waitpid(0, &status, 0)) != -1) 
    { 
     fprintf(stderr, "%d: child %d status 0x%.4X\n", 
       (int)parent, (int)corpse, status); 
    } 
} 

/* who | awk '{print $1}' | sort | uniq -c | sort -n */ 
static char *cmd0[] = { "who",    0 }; 
static char *cmd1[] = { "awk", "{print $1}", 0 }; 
static char *cmd2[] = { "sort",    0 }; 
static char *cmd3[] = { "uniq", "-c",   0 }; 
static char *cmd4[] = { "sort", "-n",   0 }; 

static char **cmds[] = { cmd0, cmd1, cmd2, cmd3, cmd4 }; 
static int ncmds = sizeof(cmds)/sizeof(cmds[0]); 

static void exec_arguments(int argc, char **argv) 
{ 
    /* Split the command line into sequences of arguments */ 
    /* Break at pipe symbols as arguments on their own */ 
    char **cmdv[argc/2];   // Way too many 
    char *args[argc+1]; 
    int cmdn = 0; 
    int argn = 0; 

    cmdv[cmdn++] = &args[argn]; 
    for (int i = 1; i < argc; i++) 
    { 
     char *arg = argv[i]; 
     if (strcmp(arg, "|") == 0) 
     { 
      if (i == 1) 
       err_sysexit("Syntax error: pipe before any command"); 
      if (args[argn-1] == 0) 
       err_sysexit("Syntax error: two pipes with no command between"); 
      arg = 0; 
     } 
     args[argn++] = arg; 
     if (arg == 0) 
      cmdv[cmdn++] = &args[argn]; 
    } 
    if (args[argn-1] == 0) 
     err_sysexit("Syntax error: pipe with no command following"); 
    args[argn] = 0; 
    exec_pipeline(cmdn, cmdv); 
} 
#include <stdio.h> 
#include <stdarg.h> 
#include <errno.h> 
#include <string.h> 
#include <stdlib.h> 
int main(int argc, char **argv) 
{ 

    printf("%s", argv[1]); 

    err_setarg0(argv[0]); 
    if (argc == 1) 
    { 
     /* Run the built in pipe-line */ 
     exec_pipeline(ncmds, cmds); 
    } 
    else 
    { 

     /* Run command line specified by user */ 
     char *original = "ls"; 
     char **pointer_to_original = &original; 
     for (int i = 0; i < argc; ++i) { printf("blarg blarg %i\n", argc); 
      printf("%s", argv[i]);// = "ls"; 
     } 
     exec_arguments(argc, argv); 
    } 
    corpse_collector(); 
    return(0); 
} 

/* stderr.c */ 
/*#include "stderr.h"*/ 
#include <stdio.h> 
#include <stdarg.h> 
#include <errno.h> 
#include <string.h> 
#include <stdlib.h> 

static const char *arg0 = "<undefined>"; 

static void err_setarg0(const char *argv0) 
{ 
    arg0 = argv0; 
} 

static void err_vsyswarn(char const *fmt, va_list args) 
{ 
    int errnum = errno; 
    fprintf(stderr, "%s:%d: ", arg0, (int)getpid()); 
    vfprintf(stderr, fmt, args); 
    if (errnum != 0) 
     fprintf(stderr, " (%d: %s)", errnum, strerror(errnum)); 
    putc('\n', stderr); 
} 

static void err_syswarn(char const *fmt, ...) 
{ 
    va_list args; 
    va_start(args, fmt); 
    err_vsyswarn(fmt, args); 
    va_end(args); 
} 

static void err_sysexit(char const *fmt, ...) 
{ 
    va_list args; 
    va_start(args, fmt); 
    err_vsyswarn(fmt, args); 
    va_end(args); 
    exit(1); 
} 
0

コマンドライン引数を解釈するのにwordexpは必要ありません。シェルはすでにあなたのためにそれをしています。 argv + 1execvpに渡すだけです。

wordexpが必要な唯一の理由は、単一の引数(例: `myutil" ls -l * .txt ")として渡されたコマンドライン全体を解釈したり、ファイルなどから読み込むことになります。しかし、なぜあなたはそのようなすべての合併症を望んでいますか?

関連する問題