【问题标题】:How can I make the system call write() print to the screen?如何使系统调用 write() 打印到屏幕上?
【发布时间】:2011-04-21 10:35:15
【问题描述】:

对于我的操作系统类,我应该只使用系统调用(没有 printf)来实现 Linux 的 cat

阅读this reference 我发现它被用于打印到文件。我想我应该操纵 ofstream。

示例中出现:ofstream outfile ("new.txt",ofstream::binary);

如何让它写入屏幕?

编辑:我意识到这个 write() 是 iostream 库的一部分,这与 int write (int fd, char *buf , int size) 系统调用相同吗?

【问题讨论】:

  • 别忘了 Linux cat 是 GNU cat 并且有 11 个不可忽略的命令行选项 ;-).linux.die.net/man/1/cat
  • 您已将此标记为C,但您正在谈论并链接到C++ 课程。这应该是C还是C++?重新编辑 - 我不会考虑允许 iostream,因为“只有系统调用”,只有 man 2 write

标签: c linux system-calls


【解决方案1】:

不,std::ostream::writewrite 系统调用不同。它确实(几乎可以肯定)使用 write 系统调用,至少在像 Linux 这样的系统上具有这样的功能,而且它通常会做非常相似的事情,但它仍然是它的一个单独的东西拥有。

不过,Linux 会为您的进程预先打开标准输入、标准输出和标准错误流。要写入屏幕,您通常会使用write(即系统调用)写入流号1 或流号2(分别是标准输出和标准错误)。

如果您需要写入屏幕,即使它们被重定向,您通常会打开一个流到/dev/tty 并(再次)使用write 写入它:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() { 
    char msg[] = "hello\n";

    int fd = open("/dev/tty", O_WRONLY);
    write(fd, msg, sizeof(msg));
    return 0;
}

【讨论】:

    【解决方案2】:
    #define _GNU_SOURCE         /* See feature_test_macros(7) */    
    #include <unistd.h> // For open, close, read, write, fsync
    #include <sys/syscall.h>  //For SYSCALL id __NR_xxx
    
    //Method 1 : API    
    write(1,"Writing via API\n",\
            strlen("Writing via API\n") ); 
    fsync(1);
    //Method 2  : Via syscall id
    const char msg[] = "Hello World! via Syscall\n";
    syscall(__NR_write, STDOUT_FILENO, msg, sizeof(msg)-1);     
    syscall(__NR_fsync, STDOUT_FILENO );    // fsync(STDOUT_FILENO);
    

    【讨论】:

      【解决方案3】:

      系统调用是Linux内核提供的服务。在 C 编程中,函数在 libc 中定义,为许多系统调用提供包装。函数调用write() 是这些系统调用之一。

      传递给write() 的第一个参数是要写入的文件描述符。符号常量STDERR_FILENOSTDIN_FILENOSTDOUT_FILENO分别定义为unidtd.h中的201 .您想写入 STDOUT_FILENOSTDERR_FILENO

      const char msg[] = "Hello World!";
      write(STDOUT_FILENO, msg, sizeof(msg)-1);

      您也可以使用syscall() 函数通过指定syscall.hunistd.h 中定义的函数号来执行间接系统调用。使用这种方法,您可以保证您只使用系统调用。您可能会发现 The Linux System Call Quick Refernence(PDF 链接)很有帮助。

      /* 4 is the system call number for write() */
      const char msg[] = "Hello World!";
      syscall(4, STDOUT_FILENO, msg, sizeof(msg)-1);

      【讨论】:

      • 奇怪,但 syscall(4...) 对我不起作用,但 syscall(1, 0, "12345\n", 6); 确实起作用。
      • @exebook 4 适用于 Mac,1 适用于 Linux
      • 系统调用参考 PDF 的链接已损坏。一个不完美的替代品可能是:syscalls.kernelgrok.com
      【解决方案4】:

      您的参考不正确。它是 C++ 的一部分,与您的作业无关。正确的参考是http://www.opengroup.org/onlinepubs/9699919799/functions/write.html

      【讨论】:

        【解决方案5】:
        #include <unistd.h>
        /* ... */
        const char msg[] = "Hello world";
        write( STDOUT_FILENO, msg, sizeof( msg ) - 1 );
        

        第一个参数是STDOUT 的文件描述符(通常是1),第二个是要写入的缓冲区,第三个是缓冲区中文本的大小(-1 是不打印零终止符) .

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-03
          • 1970-01-01
          • 2013-05-28
          • 1970-01-01
          相关资源
          最近更新 更多