Próbuję zapewnić własną implementację funkcji close()
w systemie Linux. Czemu? Ponieważ właśnie się dowiedziałem, że możesz to zrobić i brzmi to zabawnie.Zastępowanie funkcji close() w systemie Linux z moją własną funkcją close()
Oto myclose.c:
#include <stdio.h>
int close(int fd) {
printf("Closing fd: %d\n", fd);
return 0;
}
Oto mój 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
Po kompilacji, biegnę:
export LD_PRELOAD=`pwd`/myclose.so
Potem uruchom:
cat myclose.c
Wyjście pojawia się:
#include <stdio.h>
int close(int fd) {
printf("Closing fd: %d\n", fd);
return 0;
}
Closing fd: 3
Yay! Działa dobrze? Prawie. cat
dzwoni close()
więcej niż jeden raz, ale widzimy tylko jeden wiersz wyjściowy. Zgodnie z strace
(i zdrowym rozsądkiem), należy również wywołać close()
dla deskryptorów plików 1 i 2. Jeśli uruchomię cat *
i cat wszystkie pliki w katalogu, widzę "Zamykanie fd: 3", "Zamykanie fd: 4" itd. Aż do ostatniego pliku w katalogu. Ponieważ wszystkie te deskryptory plików są większe niż 2, pomyślałem, że być może wystąpił problem z zamykaniem specjalnych deskryptorów plików (stdout i stderr). Jednak po uruchomieniu ls
widzę tylko zwykłe dane wyjściowe i nie ma linii "Zamykanie fd:", co oznacza, że nie działał on również dla ls
, chociaż strace
pokazuje close(3)
podczas uruchamiania ls
.
Wszelkie pomysły na temat tego, co może być nie tak?
Mogę się tu całkowicie mylić, ale czy to nie powłoka zajmuje się FD 1 i 2? Czy próbowałeś uruchomić powłokę preinstalującą ją za pomocą "close()"? – lorenzog