簡體   English   中英

dup syscall的說明

[英]Explanation on dup syscall

  close(fileno(stdout));

  int fd = dup(fileno(stdin));
  //printf("Hello World\n");
  write(fd, "Hello", 7);

對於printf和write來說,都是在屏幕上寫Hello。.但是我認為它們不應該這樣做,因為我將stdin復制為1或stdout關閉。 並且printf連接到stdout而不是stdin但是它們仍然在打印...請說明我在理解dup時是否有任何錯誤

如果在終端上運行程序,則stdinstdout將打開同一文件-終端設備。 因此,寫入stdinfileno(stdin)dup() fileno(stdin) -寫入終端設備而您看到它並不奇怪。

如果在其他地方(例如磁盤文件)連接了stdin運行程序,則會看到不同的結果:

./program < file

由於歷史習慣, printf和代碼中的write操作恰好起作用。 這是正在發生的事情:

當用戶登錄到類Unix系統上的終端或在X11下打開終端窗口時,文件描述符0、1和2連接到終端設備,並且每個文件描述符都打開以進行讀取和寫入 盡管實際上通常只從fd 0讀取數據並寫入fd 1和2的情況仍然是這種情況。

這是第7版init.c中的代碼:

open(tty, 2);
dup(0);
dup(0);
...
execl(getty, minus, tty, (char *)0);

這是ssh工作方式:

ioctl(*ttyfd, TCSETCTTY, NULL);
fd = open("/dev/tty", O_RDWR);
if (fd < 0)
    error("%.100s: %.100s", tty, strerror(errno));
close(*ttyfd);
*ttyfd = fd;
...
/* Redirect stdin/stdout/stderr from the pseudo tty. */
if (dup2(ttyfd, 0) < 0) 
    error("dup2 stdin: %s", strerror(errno));
if (dup2(ttyfd, 1) < 0) 
    error("dup2 stdout: %s", strerror(errno));
if (dup2(ttyfd, 2) < 0) 
    error("dup2 stderr: %s", strerror(errno));

dup2函數將arg1復制到arg2中,如有必要,先關閉arg2。)

這是xterm工作方式:

if ((ttyfd = open(ttydev, O_RDWR)) >= 0) {
    /* make /dev/tty work */
    ioctl(ttyfd, TCSETCTTY, 0);
...
/* this is the time to go and set up stdin, out, and err
 */
{
/* dup the tty */
for (i = 0; i <= 2; i++)
    if (i != ttyfd) {
    IGNORE_RC(close(i));
    IGNORE_RC(dup(ttyfd));
    }
/* and close the tty */
if (ttyfd > 2)
    close_fd(ttyfd);

回到您的代碼。

close(fileno(stdout));

關閉fd 1。

int fd = dup(fileno(stdin));

這會將fd 0復制到最低可用fd中,即1,並將1分配給fd (當然,假設fd 0是打開的。)fd的0和1現在都已打開以進行讀取和寫入(假設它們已連接到終端設備)。 在Linux系統上,您可以驗證以下內容:

$ cat /proc/self/fdinfo/0
pos:    0
flags:  0100002
mnt_id: 20
$ cat /proc/self/fdinfo/1
pos:    0
flags:  0100002
mnt_id: 20

flags為in的2是常量O_RDWR ,表示已打開以進行讀取和寫入。

printf("Hello World\n");

這將寫入fd 1,該fd 1再次可以讀取和寫入終端。

write(fd, "Hello", 7);

這將再次寫入fd 1。 (但是請注意, "Hello"只有6個字節。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM