繁体   English   中英

写入stdin和从stdout读取(UNIX / LINUX / C编程)

[英]Writing to stdin and reading from stdout (UNIX/LINUX/C Programming)

我正在做一个分配,其中程序将文件描述符作为参数(通常是在exec调用中从父级获取),然后从文件中读取并写入文件描述符,在我的测试中,我意识到程序可以正常工作从命令行开始,如果我使用0、1或2作为文件描述符,则不会出错。 这对我来说很有意义,除了我可以写到stdin并将其显​​示在屏幕上。

请问对此有解释吗? 我一直以为stdin / stdout上有一些保护,您当然不能fprintf到stdin或stdout的fgets。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    char message[20];
    read(STDOUT_FILENO, message, 20);
    write(STDIN_FILENO, message, 20);

    return 0;
}

尝试在标记为只读的文件上进行写操作,反之亦然,将导致writeread操作返回-1,并且失败。 在这种特殊情况下,stdin和stdout实际上是相同的文件。 本质上,在程序执行之前(如果不执行任何重定向),外壳程序将运行:

  if(!fork()){
       <close all fd's>
       int fd = open("/dev/tty1", O_RDWR);
       dup(fd);
       dup(fd);
       execvp("name", argv);
  }

因此,stdin,out和err都是同一文件描述符的重复副本,可以打开以进行读取和写入。

read(STDIN_FILENO, message, 20); 
write(STDOUT_FILENO, message, 20);

应该管用。 注意-stdout与stdin可能不在同一位置(即使在命令行中也是如此)。 您可以将另一个进程的输出作为stdin输入到您的进程中,或将stdin / stdout安排为文件。

fprintf / fgets有一个缓冲区-从而减少了系统调用的次数。

最佳猜测-stdin指向输入来自何处,您的终端,stdout指向输出应往何处,您的终端。 由于它们都指向同一位置,因此它们是可互换的(在这种情况下)?

如果您在UNIX上运行程序

myapp < input > output

您可以打开/ proc / {pid} / fd / 1并对其进行读取,打开/ proc / {pid} / fd / 0并对其进行写入,例如,将output复制到input (执行此操作可能有更简单的方法,但我知道它可以工作)

如果您下定决心,可以做任何容易引起混淆的事情。 ;)

如果要将消息写入标准输入,可以打开当前的tty,然后调用write system call将消息写入此fd:

string console_cmd = "hello";
string tty = ttyname(STDIN_FILENO);
int fd = open(tty.c_str(), O_WRONLY);
write(fd, console_cmd.c_str(), console_cmd.size());

同样,从stdout读取。

文件描述符0、1和2都可能同时为读取和写入打开(并且实际上它们都引用相同的底层“打开文件描述”),在这种情况下,您可以执行此操作。 但是据我所知,这是无法保证的,所以它可能也不起作用。 我确实相信POSIX在某处指定如果shell调用程序时将stderr连接到终端,则它应该是可读写的,但我无法立即找到该引用。

通常,我建议不要从stdout或stderr进行读取,除非您正在寻找要从中读取密码的终端并且stdin已被重定向(不是tty)。 我建议不要写stdin-这很危险,最终可能破坏用户不希望写入的文件!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM