ºìÁªLinuxÃÅ»§
Linux°ïÖú

ÐÎÏóµÄÀí½âdupºÍdup2º¯Êý

·¢²¼Ê±¼ä:2009-08-27 14:25:55À´Ô´:ºìÁª×÷Õß:ɵµ°
ÏàÐŴ󲿷ÖÔÚUnix/Linuxϱà³ÌµÄ³ÌÐòÔ±ÊÖÍ·É϶¼ÓС¶Unix»·¾³¸ß¼¶±à³Ì¡·(APUE)Õâ±¾³¬¼¶¾­µä¾ÞÖø¡£×÷ÕßÔÚ¸ÃÊéÖн²½âdup/dup2֮ǰÔø¾­½²¹ý¡°Îļþ¹²Ïí¡±£¬Õâ¶ÔÀí½âdup/dup2»¹ÊǺÜÓаïÖúµÄ¡£ÕâÀï×ö¼òµ¥ÕªÂ¼ÒÔ±¸ÔÚºóÃæµÄ·ÖÎöÖÐʹÓãº
Stevens said:
(1) ÿ¸ö½ø³ÌÔÚ½ø³Ì±íÖж¼ÓÐÒ»¸ö¼Ç¼Ïÿ¸ö¼Ç¼ÏîÖÐÓÐÒ»ÕÅ´ò¿ªÎļþÃèÊö·û±í£¬¿É½«ÊÓΪһ¸öʸÁ¿£¬Ã¿¸öÃèÊö·ûÕ¼ÓÃÒ»Ïî¡£Óëÿ¸öÎļþÃèÊö·ûÏà¹ØÁªµÄÊÇ£º
(a) ÎļþÃèÊö·û±êÖ¾¡£
(b) Ö¸ÏòÒ»¸öÎļþ±íÏîµÄÖ¸Õë¡£
(2) ÄÚºËΪËùÓдò¿ªÎļþά³ÖÒ»ÕÅÎļþ±í¡£Ã¿¸öÎļþ±íÏî°üº¬£º
(a) Îļþ״̬±êÖ¾(¶Á¡¢Ð´¡¢Ôöд¡¢Í¬²½¡¢·Ç×èÈûµÈ)¡£
(b) µ±Ç°ÎļþλÒÆÁ¿¡£
(c) Ö¸Ïò¸ÃÎļþv½Úµã±íÏîµÄÖ¸Õë¡£
ͼʾ£º
ÎļþÃèÊö·û±í
------------
fd0 0 | p0 -------------> Îļþ±í0 ---------> vnode0
------------
fd1 1 | p1 -------------> Îļþ±í1 ---------> vnode1
------------
fd2 2 | p2
------------
fd3 3 | p3
------------
... ...
... ...
------------

Ò»¡¢µ¥¸ö½ø³ÌÄÚµÄdupºÍdup2
¼ÙÉè½ø³ÌAÓµÓÐÒ»¸öÒÑ´ò¿ªµÄÎļþÃèÊö·ûfd3£¬ËüµÄ״̬ÈçÏ£º
½ø³ÌAµÄÎļþÃèÊö·û±í(before dup2)
------------
fd0 0 | p0
------------
fd1 1 | p1 -------------> Îļþ±í1 ---------> vnode1
------------
fd2 2 | p2
------------
fd3 3 | p3 -------------> Îļþ±í2 ---------> vnode2
------------
... ...
... ...
------------

¾­ÏÂÃæµ÷Óãº
n_fd = dup2(fd3, STDOUT_FILENO);ºó½ø³Ì״̬ÈçÏ£º

½ø³ÌAµÄÎļþÃèÊö·û±í(after dup2)
------------
fd0 0 | p0
------------
n_fd 1 | p1 ------------
------------ \
fd2 2 | p2 \
------------ _\|
fd3 3 | p3 -------------> Îļþ±í2 ---------> vnode2
------------
... ...
... ...
------------
½âÊÍÈçÏ£º
n_fd = dup2(fd3, STDOUT_FILENO)±íʾn_fdÓëfd3¹²ÏíÒ»¸öÎļþ±íÏî(ËüÃǵÄÎļþ±íÖ¸ÕëÖ¸Ïòͬһ¸öÎļþ±íÏî)£¬n_fdÔÚÎļþÃèÊö·û±íÖеÄλÖÃΪ STDOUT_FILENOµÄλÖ㬶øÔ­ÏȵÄSTDOUT_FILENOËùÖ¸ÏòµÄÎļþ±íÏî±»¹Ø±Õ£¬ÎÒ¾õµÃÉÏͼӦ¸ÃºÜÇåÎúµÄ·´Ó³³öÕâµã¡£°´ÕÕÉÏÃæµÄ½âÊÍÎÒÃǾͿÉÒÔ½âÊÍCUÖÐÌá³öµÄһЩÎÊÌ⣺
(1) "dup2µÄµÚÒ»¸ö²ÎÊýÊDz»ÊDZØÐëΪÒÑ´ò¿ªµÄºÏ·¨filedes£¿" -- ´ð°¸£º±ØÐë¡£
(2) "dup2µÄµÚ¶þ¸ö²ÎÊý¿ÉÒÔÊÇÈÎÒâºÏ·¨·¶Î§µÄfiledesֵô£¿" -- ´ð°¸£º¿ÉÒÔ£¬ÔÚUnixÆäÈ¡ÖµÇø¼äΪ[0,255]¡£

ÁíÍâ¸Ð¾õÀí½âdup2µÄÒ»¸öºÃ·½·¨¾ÍÊÇ°Ñfd¿´³ÉÒ»¸ö½á¹¹ÌåÀàÐÍ£¬¾ÍÈçÉÏÃæͼÐÎÖл­µÄÄÇÑù£¬ÎÒÃDz»·Á°ÑÖ®¶¨ÒåΪ£º
struct fd_t {
int index;
filelistitem *ptr;
};
È»ºódup2Æ¥Åäindex£¬ÐÞ¸Äptr£¬Íê³Édup2²Ù×÷¡£

ÔÚѧϰdup2ʱ×ÜÊÇÅöµ½¡°Öض¨Ïò¡±Ò»´Ê£¬ÉÏͼÍê³ÉµÄ¾ÍÊÇÒ»¸ö¡°´Ó±ê×¼Êä³öµ½ÎļþµÄÖض¨Ïò¡±£¬¾­¹ýdup2ºó½ø³ÌAµÄÈκÎÄ¿±êΪSTDOUT_FILENOµÄI/O²Ù×÷ÈçprintfµÈ£¬ÆäÊý¾Ý¶¼½«Á÷Èëfd3Ëù¶ÔÓ¦µÄÎļþÖС£ÏÂÃæÊÇÒ»¸öÀý×Ó³ÌÐò£º
#define TESTSTR "Hello dup2\n"
int main() {
int fd3;

fd3 = open("testdup2.dat", 0666);
if (fd < 0) {
printf("open error\n");
exit(-1);
}

if (dup2(fd3, STDOUT_FILENO) < 0) {
printf("err in dup2\n");
}
printf(TESTSTR);
return 0;
}
Æä½á¹û¾ÍÊÇÄãÔÚtestdup2.datÖп´µ½"Hello dup2"¡£

¶þ¡¢Öض¨Ïòºó»Ö¸´
CUÉÏÓÐÕâÑùÒ»¸öÌû×Ó£¬¾ÍÊÇÈçºÎÔÚÖض¨ÏòºóÔÙ»Ö¸´Ô­À´µÄ״̬£¿Ê×ÏÈ´ó¼Ò¶¼ÄÜÏëµ½Òª±£´æÖض¨ÏòÇ°µÄÎļþÃèÊö·û¡£ÄÇôÈçºÎÀ´±£´æÄØ£¬ÏóÏÂÃæÕâÑùÐÐô£¿
int s_fd = STDOUT_FILENO;
int n_fd = dup2(fd3, STDOUT_FILENO);
»¹ÊÇÕâÑù¿ÉÒÔÄØ£¿
int s_fd = dup(STDOUT_FILENO);
int n_fd = dup2(fd3, STDOUT_FILENO);
ÕâÁ½ÖÖ·½·¨µÄÇø±ðµ½µ×ÔÚÄÄÄØ£¿´ð°¸ÊǵڶþÖÖ·½°¸²ÅÊÇÕýÈ·µÄ£¬·ÖÎöÈçÏ£º°´ÕÕµÚÒ»ÖÖ·½·¨£¬ÎÒÃǽö½öÔÚ"±íÃæÉÏ"±£´æÁËÏ൱ÓÚfd_t£¨°´ÕÕÎÒÇ°Ãæ˵µÄÀí½â·½·¨£©ÖеÄindex£¬¶øÔÚµ÷ÓÃdup2Ö®ºó£¬ptrËùÖ¸ÏòµÄÎļþ±íÏîÓÉÓÚ¼ÆÊýÖµÒÑΪÁã¶ø±»¹Ø±ÕÁË£¬ÎÒÃÇÈç¹ûÔÙµ÷ÓÃdup2(s_fd, fd3)¾Í»á³ö´í(³ö´íÔ­ÒòÉÏÃæÓнâÊÍ)¡£¶øµÚ¶þÖÖ·½·¨ÎÒÃÇÊ×ÏÈ×öһϸ´ÖÆ£¬¸´ÖƺóµÄ״̬ÈçÏÂͼËùʾ:
½ø³ÌAµÄÎļþÃèÊö·û±í(after dup)
------------
fd0 0 | p0
------------
fd1 1 | p1 -------------> Îļþ±í1 ---------> vnode1
------------ /|
fd2 2 | p2 /
------------ /
fd3 3 | p3 -------------> Îļþ±í2 ---------> vnode2
------------ /
s_fd 4 | p4 ------/
------------
... ...
... ...
------------

µ÷ÓÃdup2ºó״̬Ϊ£º
½ø³ÌAµÄÎļþÃèÊö·û±í(after dup2)
------------
fd0 0 | p0
------------
n_fd 1 | p1 ------------
------------ \
fd2 2 | p2 \
------------ _\|
fd3 3 | p3 -------------> Îļþ±í2 ---------> vnode2
------------
s_fd 4 | p4 ------------->Îļþ±í1 ---------> vnode1
------------
... ...
... ...
------------
dup(fd)µÄÓïÒâÊÇ·µ»ØµÄеÄÎļþÃèÊö·ûÓëfd¹²ÏíÒ»¸öÎļþ±íÏî¡£¾ÍÈçafter dupͼÖеÄs_fdºÍfd1¹²ÏíÎļþ±í1Ò»Ñù¡£

È·¶¨µÚ¶þ¸ö·½°¸ºóÖض¨ÏòºóµÄ»Ö¸´¾ÍºÜÈÝÒ×ÁË£¬Ö»Ðèµ÷ÓÃdup2(s_fd, n_fd);¼´¿É¡£ÏÂÃæÊÇÒ»¸öÍêÕûµÄÀý×Ó³ÌÐò£º
#define TESTSTR "Hello dup2\n"
#define SIZEOFTESTSTR 11

int main() {
int fd3;
int s_fd;
int n_fd;

fd3 = open("testdup2.dat", 0666);
if (fd3 < 0) {
printf("open error\n");
exit(-1);
}

/* ¸´ÖƱê×¼Êä³öÃèÊö·û */
s_fd = dup(STDOUT_FILENO);
if (s_fd < 0) {
printf("err in dup\n");
}

/* Öض¨Ïò±ê×¼Êä³öµ½Îļþ */
n_fd = dup2(fd3, STDOUT_FILENO);
if (n_fd < 0) {
printf("err in dup2\n");
}
write(STDOUT_FILENO, TESTSTR, SIZEOFTESTSTR); /* дÈëtestdup2.datÖÐ */

/* Öض¨Ïò»Ö¸´±ê×¼Êä³ö */
if (dup2(s_fd, n_fd) < 0) {
printf("err in dup2\n");
}
write(STDOUT_FILENO, TESTSTR, SIZEOFTESTSTR); /* Êä³öµ½ÆÁÄ»ÉÏ */
return 0;
}
×¢ÒâÕâÀïÎÒÔÚÊä³öÊý¾ÝµÄʱºòÎÒÊÇÓÃÁ˲»´ø»º³åµÄwrite¿âº¯Êý£¬Èç¹ûʹÓôø»º³åÇøµÄprintf£¬Ôò×îÖÕ½á¹ûΪÆÁÄ»ÉÏÊä³öÁ½ÐÐ"Hello dup2"£¬¶øÎļþtestdup2.datÖÐΪ¿Õ£¬Ô­Òò¾ÍÊÇ»º³åÇø×÷¹Ö£¬ÓÉÓÚ×îÖÕµÄÄ¿±êÊÇÆÁÄ»£¬ËùÒÔ³ÌÐò×îºó½«»º³åÇøµÄÄÚÈݶ¼Êä³öµ½ÆÁÄ»¡£


Èý¡¢¸¸×Ó½ø³Ì¼äµÄdup/dup2
ÓÉforkµ÷Óõõ½µÄ×Ó½ø³ÌºÍ¸¸½ø³ÌµÄÏàͬÎļþÃèÊö·û¹²ÏíͬһÎļþ±íÏÈçÏÂͼËùʾ£º
¸¸½ø³ÌAµÄÎļþÃèÊö·û±í
------------
fd0 0 | p0
------------
fd1 1 | p1 -------------> Îļþ±í1 ---------> vnode1
------------ /|\
fd2 2 | p2 |
------------ |
|
×Ó½ø³ÌBµÄÎļþÃèÊö·û±í |
------------ |
fd0 0 | p0 |
------------ |
fd1 1 | p1 ---------------------|
------------
fd2 2 | p2
------------
ËùÒÔÇ¡µ±µÄÀûÓÃdup2ºÍdup¿ÉÒÔÔÚ¸¸×Ó½ø³ÌÖ®¼ä½¨Á¢Ò»Ìõ¡°¹µÍ¨µÄÇÅÁº¡±¡£ÕâÀï²»ÏêÊö¡£

ËÄ¡¢Ð¡½á
Áé»îµÄÀûÓÃdup/dup2¿ÉÒÔ¸øÄã´øÀ´ºÜ¶àÇ¿´óµÄ¹¦ÄÜ£¬»¨ÁËһЩʱ¼ä×ܽá³öÉÏÃæÄÇô¶à£¬²»ÖªµÀ×Ô¼ºÀí½âµÄÊÇ·ñ͸³¹£¬Ö»ÄÜÔÚÒÔºóµÄʵ¼ùÖÐÂýÂý̽Ë÷ÁË¡£

²Î¿¼×ÊÁÏ£º
1¡¢¡¶Unix»·¾³¸ß¼¶±à³Ì¡·
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 4 ÌõÆÀÂÛ

  1. daxuizi ÓÚ 2010-11-10 16:40:44·¢±í:

    ѧϰÁË

  2. whyliyi ÓÚ 2010-11-04 15:27:10·¢±í:

    ¶÷£¬ÃÔãÁ˺þã¬Õâ¸öº¯Êý¡£
    ÏÖÔÚѧϰÍøÂç±à³Ì£¬·¢ÏÖÕⶫÎ÷ºÜ¸ßÉî°¢£¡Ïëд¸öºÃµã³ÌÐò²»ÈÝÒ×£¡

  3. huofootball ÓÚ 2009-08-27 18:29:52·¢±í:

    lzÍæµÄÊǸ߼¶±à³Ì£¿

  4. jcmatio ÓÚ 2009-08-27 15:14:37·¢±í:

    Ì«ÉîÁË£¬»¹¿´²»¶®