2014-04-28 8 views
6

Sto cercando di fornire la mia implementazione della funzione close() in Linux. Perché? Perché ho appena scoperto che potresti farlo e sembra divertente.Sostituzione della funzione close() in Linux con la mia funzione close()

Ecco myclose.c:

#include <stdio.h> 

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

Ecco il mio makefile:

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 

Dopo la compilazione, corro:

export LD_PRELOAD=`pwd`/myclose.so 

Poi corro:

cat myclose.c 

L'output che ottengo è:

#include <stdio.h> 

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

Yay! Funziona bene? Quasi. cat chiama close() più di una volta, ma vediamo solo una riga di output. Secondo strace (e buon senso), per i descrittori di file 1 e 2 è necessario chiamare anche close(). Se eseguo cat * e cat i file nella directory, vedo "Closing fd: 3", "Closing fd: 4", ecc. Fino all'ultimo file nella directory. Poiché tutti questi descrittori di file sono maggiori di 2, ho pensato che forse c'era un problema con la chiusura dei descrittori di file speciali (stdout e stderr). Tuttavia, quando corro ls vedo solo l'output regolare e nessuna riga "Closing fd:", il che significa che non ha funzionato neanche per ls, anche se strace mostra close(3) quando è in esecuzione ls.

Qualche idea su cosa potrebbe essere sbagliato?

+0

Potrei sbagliare completamente qui, ma il guscio non si occupa di FD 1 e 2? Hai provato a lanciare una shell che lo precarica con il tuo "close()"? – lorenzog

risposta

1

Sono sorpreso che ha funzionato bene come ha fatto!

Si sta sostituendo la voce della libreria C per close(), non la chiamata di sistema. Tuttavia, altre parti della libreria C vengono ancora utilizzate per questi programmi. Probabilmente c'è qualche collegamento diretto ai primi 3 handle di file. Dai un'occhiata all'origine della libreria C che stai utilizzando.

2

Questo tipo di "sostituzione" funziona solo per i programmi collegati dinamicamente.

Qualsiasi programma collegato statico alla libreria che implementa la chiamata close non riuscirebbe a "sostituirlo".

Quest'ultimo sarà il caso per ogni chiamata a close() fuori dalla libreria che implementa l'originale close() stesso. E sembra anche il caso dei descrittori di file standard 0, 1 e 2 poiché la loro chiusura molto probabilmente è implementata nella stessa libreria, cioè nell'implementazione di libc in uso.