2016-09-22 2 views
0

Eine Weiterleitung stdout mit close und open:dup2 vs schließen + offen für stdout Umleitung

close(STDOUT_FILENO); 
int fd = open("log", O_RDWR); 
printf("My output\n"); 

von Umleitung unterscheidet durch dup2:

int fd = open("log", O_RDWR); 
dup2(fd, STDOUT_FILENO); 
printf("My output\n"); 

mit strace ich sehe, dass im ersten Fall write kehrt EBADF :

$ strace -e write ./a.out 
write(1, "My output\n", 10)  = -1 EBADF (Bad file descriptor) 

Wie unterscheidet sich dup2 von open + close?

Antwort

0

Wenn Sie das tun

int fd = open("log", O_RDWR); 

Die offene Datei kann jeder Dateideskriptor sein. Nur weil Sie STDOUT_FILENO geschlossen haben, heißt das nicht, dass es für open() verwendet wird. Selbst wenn das System die ersten verfügbaren Deskriptoren auswählte (etwas, das nicht garantiert ist), ist es dennoch möglich, dass:

  • stdin ebenfalls geschlossen ist und zuerst ausgewählt würde.
  • ein Signal wird zwischen close() und open() ausgeführt und der Signal-Handler öffnet eine Datei.
  • die open() schlägt fehl, so dass Sie mit einem geschlossenen stdout.
  • Die Version dup2() andererseits stellt sicher, dass der Dateideskriptor korrekt ist, indem er explizit angegeben wird. Außerdem ist garantiert atomar. Das heißt, zu jedem Zeitpunkt ist STDOUT_FILENO gültig und entweder ist es immer noch der alte, oder es ist der neue und der alte wurde geschlossen.

    Als Nebenbemerkung, nach einer dup2, beide Deskriptor-Nummern beziehen sich auf die gleiche Datei, und beide müssen close() ed sein. Also, wenn Sie nur stdout umleiten, möchten Sie wahrscheinlich close(fd) nach dem Anruf.

    +0

    Ich habe diese Frage gestellt, nachdem ich verifiziert habe, dass 'fd', das von' open' zurückgegeben wurde, gleich 'STDOUT_FILENO' ist. Die Lieferung eines Signals ist ja möglich, ist aber nicht der Fall. Da ist niemand von Ihrem Szenario hier, in dem die beiden Methoden unterschiedlich sind? – MirkoBanchi

    Verwandte Themen