[英]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時是否有任何錯誤
如果在終端上運行程序,則stdin
和stdout
將打開同一文件-終端設備。 因此,寫入stdin
或fileno(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.