我必须为此功能编写代码(针对大学),该功能必须:


拨打系统电话pipe()
调用fcntl(),这样管道的文件描述符将被执行程序关闭
重定向pipes[1]上right_cmd的输出
重定向pipes[0]上的left_cmd的输入


结构:

enum next_action {
    NA_QUIT,
    NA_CONTINUE
};

#define NO_REDIR (-1)

struct shell {
    struct var_table *vars;
    char **environment;
};

struct var_table {
    size_t len;
    size_t capacity;
    struct var *vars;
};

struct var {
   char *name;
   char *value;
};

struct node {
#ifdef DEBUG
   void (*dump_to_stdout)(const struct node * const this);
#endif /*#ifdef DEBUG */
   int (*are_redirections_ok)(const struct node * const this, int   ok_in_redir, int ok_out_redir);
   enum next_action (*execute)(const struct node * const this, struct shell  * const sh, int in_redir, int out_redir);
   void (*destroy)(struct node * const this);
   void *impl;
 };

struct pipe_impl {
    struct node *left_cmd;
    struct node *right_cmd;
};


新的管道节点功能:

 struct node *new_node_pipe(struct node * const left_cmd, struct node * const right_cmd) {
    struct node *n = new_node_empty();
    struct pipe_impl *impl;
    assert(left_cmd);
    assert(right_cmd);
#ifdef DEBUG
    n->dump_to_stdout = pipe_dump_to_stdout;
#endif /* #ifdef DEBUG */
    n->are_redirections_ok = pipe_are_redirections_ok;
    n->execute = pipe_execute;
    n->destroy = pipe_destroy;
    impl = n->impl = my_malloc(sizeof(struct pipe_impl));
    impl->left_cmd = left_cmd;
    impl->right_cmd = right_cmd;
    return n;
  }


我要做的功能:

enum next_action pipe_execute(const struct node * const this, struct shell * const sh, int in_redir, int out_redir)
{
    int pipes[2];
    int i;
    struct pipe_impl *impl = this->impl;

    if(pipe(pipes)<0)
        fail_errno("can not create pipe\n");
    for(i=0;i<2;i++)
        if(fcntl(pipes[i],F_SETFD,FD_CLOEXEC)<0)
            fail_errno("fcntl error pipes\n");
  /* ?????????????
   ?????????????*/
    return NA_CONTINUE;
}


问题是我不知道该怎么做第3点和第4点:S
有什么建议吗?非常感谢你:)

最佳答案

来自man dup2


  dup2()
         dup2()系统调用执行与dup()相同的任务,但是
         使用编号最小的未使用文件描述符,它使用文件
         newfd中指定的描述符编号。如果文件描述符为newfd
         以前是打开的,在重用之前已被静默关闭。
  
  关闭和重用文件描述符newfd的步骤是
         原子执行。这很重要,因为尝试实施
         使用close(2)和dup()的等效功能将受到
         竞争条件,因此newfd可以在两个步骤之间重用。
         之所以会发生这种重用,是因为主程序被一个
         分配文件描述符的信号处理程序,或者因为
         并行线程分配文件描述符。
  
  请注意以下几点:
  
  
  如果oldfd不是有效的文件描述符,则调用失败,并且
        newfd未关闭。
  如果oldfd是有效的文件描述符,并且newfd具有相同的值
        与oldfd一样,则dup2()不执行任何操作,并返回newfd。
  


也许

if (dup2(pipes[1], out_redir) == -1) {
    /* Handle dup2() error */
}
if (dup2(pipes[0], in_redir) == -1) {
    /* Handle dup2() error */
};

关于c - 用c编码bash:不了解如何实现管道,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47453646/

10-15 01:16