View previous topic :: View next topic |
Author |
Message |
Mr. Anderson l33t
Joined: 22 Apr 2004 Posts: 762
|
Posted: Sun Dec 30, 2007 11:13 pm Post subject: [glibc]Definition von rmdir |
|
|
Die coreutils enthalten diverse kleine Werkzeuge wie rm, touch, tee, mkdir usw. und eben auch rmdir. Nun wollte ich den konkreten Systemaufruf finden, wo ein Verzeichnis dann effektiv gelöscht wird. In der rmdir.c der coreutils wird eine Funktion
Code: | int rmdir(char *path) |
verwendet. Für diese Funktion ist kein include notwendig. Daraus habe ich gefolgert, dass sie in der glibc implementiert sein muss. Also habe glibc auseinandergenommen. Aber dort hänge ich fest. Man findet viele Implementierungen für rmdir, aber keine davon ergibt für mich Sinn. Da ist einmal io/rmdir.c:
Code: | #include <errno.h>
#include <stddef.h>
#include <unistd.h>
/* Remove the directory PATH. */
int
__rmdir (path)
const char *path;
{
if (path == NULL)
{
__set_errno (EINVAL);
return -1;
}
__set_errno (ENOSYS);
return -1;
}
stub_warning (rmdir)
weak_alias (__rmdir, rmdir)
#include <stub-tag.h> |
Das ist nur ein Stub
und dann gibt es da
sysdeps/unix/rmdir.c
Code: | #include <errno.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
/* Create a directory named PATH with protections MODE. */
int
__rmdir (path)
const char *path;
{
char *cmd = __alloca (80 + strlen (path));
char *p;
int status;
int save;
struct stat statbuf;
if (path == NULL)
{
__set_errno (EINVAL);
return -1;
}
/* Check for some errors. */
if (__stat (path, &statbuf) < 0)
return -1;
if (!S_ISDIR (statbuf.st_mode))
{
__set_errno (ENOTDIR);
return -1;
}
p = cmd;
*p++ = 'r';
*p++ = 'm';
*p++ = 'd';
*p++ = 'i';
*p++ = 'r';
*p++ = ' ';
strcpy (p, path);
save = errno;
/* If system doesn't set errno, but the rmdir fails, we really
have no idea what went wrong. EIO is the vaguest error I
can think of, so I'll use that. */
__set_errno (EIO);
status = system (cmd);
if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
{
return 0;
__set_errno (save);
}
else
return -1;
}
weak_alias (__rmdir, rmdir) |
Da verwirrt mich einerseits der Kommentar am Anfang etwas: "Create a directory..."
und andererseits sehe ich da die Zeile
Code: | status = system (cmd); |
Ich bin kein erfahrener C-Hacker... daher irre ich mich vielleicht. Ist int system (char *cmd) nicht die Ausführung eines externen Programms? Wird an dieser Stelle nicht /bin/rmdir ausgeführt? Wenn nicht: was dann?
Und: wo ist nun der Code, den ich suche? Worauf greifen die coreutils zurück, wenn sie die Funktion rmdir aufrufen? |
|
Back to top |
|
|
manuels Advocate
Joined: 22 Nov 2003 Posts: 2146 Location: Europe
|
|
Back to top |
|
|
blu3bird Retired Dev
Joined: 04 Oct 2003 Posts: 614 Location: Munich, Germany
|
Posted: Mon Dec 31, 2007 1:24 am Post subject: |
|
|
Code: | #include <unistd.h>
main() {
rmdir("/tmp/bla");
} |
Für weitere Infos: man 2 rmdir _________________ Black Holes are created when God divides by zero! |
|
Back to top |
|
|
Mr. Anderson l33t
Joined: 22 Apr 2004 Posts: 762
|
Posted: Mon Dec 31, 2007 2:13 am Post subject: |
|
|
manuels wrote: | hmm, such mal nach einem Aufruf wie
Code: | syscall(SYS_rmdir, directory) |
|
Habe alles durchgegrept nach syscall in Zusammenhang mit rmdir und habe nach ${GROSSBUCHSTABENPRAEFIX}_rmdir gesucht. Das war fast alles entweder nur für einzelne, spezielle Systeme oder Architekturen (z. B. solaris2@sparc) oder es war nicht hilfreich.
das Meistversprechende, was ich gefunden habe, ist
Code: | #### CALL=rmdir NUMBER=40 ARGS=i:s SOURCE=-
ifeq (,$(filter rmdir,$(unix-syscalls)))
unix-syscalls += rmdir
$(foreach o,$(object-suffixes),$(objpfx)rmdir$o) $(foreach o,$(object-suffixes),$(objpfx)ptw-rmdir$o) $(objpfx)rtld-rmdir.os: \
$(common-objpfx)s-proto.d
$(make-target-directory)
(echo '#include <sysdep.h>'; \
echo 'PSEUDO (__rmdir, rmdir, 1)'; \
echo ' ret'; \
echo 'PSEUDO_END(__rmdir)'; \
echo 'libc_hidden_def (__rmdir)'; \
echo 'weak_alias (__rmdir, rmdir)'; \
echo 'libc_hidden_weak (rmdir)'; \
) | $(compile-syscall)
endif
ifeq (,$(filter rmdir,$(bp-thunks)))
bp-thunks += rmdir
$(objpfx)$(bppfx)rmdir.ob: $(common-objpfx)s-proto-bp.d
(echo '#define __rmdir(s1) i0v; \'; \
echo 'extern char s1v; \'; \
echo '__typeof (i0v) BP_SYM (__rmdir) (__typeof (s1v) *__bounded s1a) { \'; \
echo ' extern __typeof (i0v) (__rmdir) (__typeof (s1v) *__unbounded); \'; \
echo ' return (__rmdir) (CHECK_STRING (s1a)); \'; \
echo '} \'; \
echo 'libc_hidden_def (BP_SYM (__rmdir)) \'; \
echo 'weak_alias (BP_SYM (__rmdir), BP_SYM (rmdir)) \'; \
echo 'libc_hidden_weak (BP_SYM (rmdir)) \'; \
echo ''; \
echo '#include <bp-thunks.h>'; \
) | $(COMPILE.c) -x c -o $@ -
endif |
aus der Datei sysd-syscalls, die im build-Verzeichnis beim Aufruf von make erstellt wird.
Das sieht so aus als würden sich da noch, shell, make und der Präprozessor richtig austoben und die Wrapper um die System-Calls vollautomatisch generieren. Kann das sein? Wird der Code vielleicht nur temporär generiert, gleich in object-Dateien übersetzt und wieder gelöscht? |
|
Back to top |
|
|
Mr. Anderson l33t
Joined: 22 Apr 2004 Posts: 762
|
Posted: Wed Jan 02, 2008 3:51 pm Post subject: |
|
|
Das beantworte ich nun selbst: ja, es wird vollautomatisch generiert. Das nachzuvollziehen dauert ein ganzes Weilchen und führt am Ende zu einer Mischung aus C und Assembler. Jedenfalls werden die Parameter in der Regel direkt an den Kernel durchgereicht. Man kann es sich also einfach machen und so tun als wäre int rmdir(char *path) direkt ein Aufruf von Kernel-Code. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|