【问题标题】:In C, how do I redirect STDOUT_FILENO to /dev/null using dup2 and then redirect back to its original value later?在 C 中,如何使用 dup2 将 STDOUT_FILENO 重定向到 /dev/null,然后稍后再重定向回其原始值?
【发布时间】:2013-01-28 14:22:05
【问题描述】:

我正在处理一项任务,但我很难完成它。这个想法是编写一个程序 if.c 来执行一个程序,如果成功则执行第二个程序。我应该抑制第一个程序的标准输出并取消第二个程序的标准输出。我在多个测试中收到错误消息。例如:“./if echo no then echo yes”返回“echo:write error: Bad file descriptor”。我试过在网上找出我做错了什么,但没有运气。

这是我的代码:

#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include "tlpi_hdr.h"

int main(int argc, char *argv[])
{
    if(argc < 4){
        fprintf(stderr,"Incorrect number of arguments.\n");
        exit(EXIT_FAILURE);
    }

    int thenArg = 0;
    char then[4];
    strcpy(then,"then");
    for(int x=1; x<argc; x++){
        if(strncmp(argv[x], then, 4) == 0) thenArg = x;
    }

    if(thenArg == 0){
        fprintf(stderr,"No 'then' argument found.\n");
        exit(EXIT_FAILURE);
    }

    int save_out = dup(STDOUT_FILENO);
    if(save_out == -1){
        fprintf(stderr,"Error in dup(STDOUT_FILENO)\n");
        exit(EXIT_FAILURE);
    }

    int devNull = open("/dev/null",0);
    if(devNull == -1){
        fprintf(stderr,"Error in open('/dev/null',0)\n");
        exit(EXIT_FAILURE);
    }

    int dup2Result = dup2(devNull, STDOUT_FILENO);
    if(dup2Result == -1) {
        fprintf(stderr,"Error in dup2(devNull, STDOUT_FILENO)\n");
        exit(EXIT_FAILURE);
    }

    int program1argLocation = 1;
    int program2argLocation = thenArg + 1;
    int program1argCount = thenArg-1;
    int program2argCount = argc-(program2argLocation);
    char *program1args[program1argCount+1];
    char *program2args[program2argCount+1];

    for(int i=0; i<program1argCount; i++){
        program1args[i]=argv[program1argLocation + i];
    }
    program1args[program1argCount] = NULL;
    for(int i=0; i<program2argCount; i++){
        program2args[i]=argv[program2argLocation + i];
    }
    program2args[program2argCount] = NULL;

    pid_t pid = fork();
    int child_status;
    switch (pid) {
    case -1:
        fprintf(stderr,"Fork failed\n");
        exit(EXIT_FAILURE);

    case 0: //child
        //child will run program 1
        if(execvp(program1args[0],&program1args[0]) == -1){
            fprintf(stderr,"Program 1 Failed.\n");
            exit(EXIT_FAILURE);
        }  

    default: //parent
        //parent will run program2
        pid = wait(&child_status);

        if(WEXITSTATUS(child_status) == 0){
            dup2(save_out, STDOUT_FILENO);

            int prog2status = execvp(program2args[0],&program2args[0]);
            if(prog2status == -1) {
                fprintf(stderr,"Program 2 failed.\n");
                exit(EXIT_FAILURE);
            }  
        }  
    }  

}  

【问题讨论】:

  • char then[4]; strcpy(then, "then"); 是缓冲区溢出。为什么不直接使用if(0 == strcmp(argv[x], "then"))if(0 == strncmp(argv[x], "then", 4))
  • 我想我第一次实现它时尝试过,但遇到了某种错误。我会记住这一点,并在下次遇到同样的事情时再参考它。谢谢!还不习惯 C,所以任何这样的输入都很棒。

标签: c fork stdout dup2 dup


【解决方案1】:

你的错误在这里:

int devNull = open("/dev/null",0);

要将devNull用作STDOUT_FILENO,必须打开才能写入:

int devNull = open("/dev/null", O_WRONLY);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-15
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 2011-05-14
    • 2012-01-03
    相关资源
    最近更新 更多