不使用dup2()实现execvp()输出重定向到文件的替代方法有哪些
不用dup2实现execvp输出重定向的替代方案
重定向execvp子进程标准输出到文件的核心逻辑是让子进程的1号文件描述符(标准输出)指向目标文件,dup2是最常用的显式实现方案,确实存在以下几种替代实现:
close()+dup()组合实现
利用类Unix系统dup()会返回当前最小可用文件描述符的规则,先关闭标准输出的1号描述符,再调用dup()复制open返回的目标文件描述符,就会自动把目标文件绑定到1号描述符:int target_fd = open("output.log", O_WRONLY | O_CREAT | O_TRUNC, 0644); close(STDOUT_FILENO); // 释放1号描述符 dup(target_fd); // 自动把target_fd复制到最小可用的1号描述符 close(target_fd); execvp(cmd_arr[0], cmd_arr);注意:需要保证
close(STDOUT_FILENO)到dup()之间没有任何打开新文件描述符的操作,否则dup()返回的描述符就不是1,重定向会失效。fcntl()结合F_DUPFD命令实现fcntl()的F_DUPFD命令支持指定返回的最小文件描述符编号,提前关闭1号描述符后,指定最小返回值为1即可实现和上述dup()相同的效果,还可以搭配F_DUPFD_CLOEXEC标志自动设置关闭即执行属性,避免文件描述符泄漏:int target_fd = open("output.log", O_WRONLY | O_CREAT | O_TRUNC, 0644); close(STDOUT_FILENO); fcntl(target_fd, F_DUPFD, STDOUT_FILENO); close(target_fd); execvp(cmd_arr[0], cmd_arr);直接打开文件到1号描述符
连dup/fcntl都不需要调用,直接利用open()返回最小可用描述符的规则,提前关闭1号描述符后直接打开目标文件,open()会自动把目标文件绑定到1号描述符:close(STDOUT_FILENO); open("output.log", O_WRONLY | O_CREAT | O_TRUNC, 0644); // open返回值为1,直接绑定标准输出 execvp(cmd_arr[0], cmd_arr);注意:该方案对执行时序要求最高,
close(1)到open()之间不能有任何操作占用新的文件描述符,鲁棒性最低。
以上方案本质上都是依赖文件描述符的分配规则实现,没有
dup2()显式指定目标描述符的逻辑鲁棒,生产环境优先选择dup2()更稳妥。
内容的提问来源于stack exchange,提问作者Belly
相关产品推荐
相关产品推荐

