2014-04-28 12 views
6

Ich versuche, meine eigene Implementierung der close() Funktion in Linux bereitzustellen. Warum? Weil ich gerade herausgefunden habe, dass du das kannst und es hört sich lustig an.Ersetzen Sie die Close() -Funktion in Linux mit meiner eigenen close() -Funktion

Hier myclose.c:

#include <stdio.h> 

int close(int fd) { 
    printf("Closing fd: %d\n", fd); 
    return 0; 
} 

Hier ist mein Make-Datei:

all: myclose.so my-close.so 

%.so: %.o 
    gcc -shared -o [email protected] $< 

%.o:%.c 
    gcc -c -fPIC -o [email protected] $< 

clean: 
    rm -f *.so *.o 

Nach dem Übersetzen, ich laufe:

export LD_PRELOAD=`pwd`/myclose.so 

Dann laufe ich:

cat myclose.c 

Der Ausgang ich erhalte, ist:

#include <stdio.h> 

int close(int fd) { 
    printf("Closing fd: %d\n", fd); 
    return 0; 
} 
Closing fd: 3 

Yay! Funktioniert richtig? Fast. cat Aufrufe close() mehr als einmal, aber wir sehen nur eine Zeile der Ausgabe. Nach strace (und gesunden Menschenverstand) sollte close() auch für Dateideskriptoren 1 und 2 aufgerufen werden. Wenn ich cat * ausführen und alle Dateien im Verzeichnis cat, sehe ich "Closing fd: 3", "Closing fd: 4" usw. bis zur letzten Datei im Verzeichnis. Da alle diese Dateideskriptoren größer als 2 sind, dachte ich, dass es vielleicht ein Problem beim Schließen der speziellen Dateideskriptoren (stdout und stderr) gab. Wenn ich jedoch ls ausführen sehe ich nur die reguläre Ausgabe und keine "Closing fd:" Zeilen, was bedeutet, dass es nicht für ls entweder funktioniert, obwohl strace 10 zeigt, wenn ls ausgeführt wird.

Irgendwelche Ideen, was könnte falsch sein?

+0

Ich könnte hier völlig falsch sein, aber ist nicht die Shell kümmert sich FD 1 und 2? Hast du versucht, eine Shell zu starten, die es mit deinem "close()" vorlädt? – lorenzog

Antwort

1

Ich bin überrascht, es hat so gut funktioniert wie es!

Sie ersetzen den C-Bibliothekseintrag für close(), nicht den Systemaufruf. Andere Teile der C-Bibliothek werden jedoch weiterhin für diese Programme verwendet. Wahrscheinlich gibt es eine direkte Verbindung zu den ersten drei Dateigriffen. Sehen Sie sich die Quelle der von Ihnen verwendeten C-Bibliothek an.

2

Diese Art von "Ersatz" funktioniert nur für dynamisch verknüpfte Programme.

Jedes Programm, das statisch mit der Bibliothek verbunden ist, die den close-Aufruf implementiert, würde es nicht ersetzen lassen.

Letzteres ist der Fall für jeden Aufruf von close() aus der Bibliothek, die das ursprüngliche close() selbst implementiert. Und es scheint auch der Fall zu sein für die Standard-Dateideskriptoren 0, 1 und 2, da deren Abschluss am wahrscheinlichsten in derselben Bibliothek implementiert ist, das heißt in der verwendeten libc-Implementierung.