diff options
-rw-r--r-- | libc/sysdeps/linux/common/Makefile | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/getcwd.c (renamed from libc/unistd/getcwd.c) | 45 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/syscalls.c | 8 | ||||
-rw-r--r-- | libc/unistd/Makefile | 2 |
4 files changed, 46 insertions, 11 deletions
diff --git a/libc/sysdeps/linux/common/Makefile b/libc/sysdeps/linux/common/Makefile index e3098f409..a7a254cc5 100644 --- a/libc/sysdeps/linux/common/Makefile +++ b/libc/sysdeps/linux/common/Makefile @@ -29,7 +29,7 @@ ifeq ($(strip $(DOPIC)),true) SAFECFLAGS+=-fPIC endif -CSRC= waitpid.c statfix.c getdnnm.c gethstnm.c \ +CSRC= waitpid.c statfix.c getdnnm.c gethstnm.c getcwd.c \ mkfifo.c setegid.c wait.c getpagesize.c seteuid.c \ wait3.c setpgrp.c getdtablesize.c create_module.c ptrace.c \ cmsg_nxthdr.c statfix64.c longjmp.c open64.c ftruncate64.c \ diff --git a/libc/unistd/getcwd.c b/libc/sysdeps/linux/common/getcwd.c index fd1e29445..1ec00a36e 100644 --- a/libc/unistd/getcwd.c +++ b/libc/sysdeps/linux/common/getcwd.c @@ -7,11 +7,52 @@ #include <string.h> #include <sys/syscall.h> -/* if the syscall is not present, we have to recurse up */ -#ifndef __NR_getcwd +#ifdef __NR_getcwd +#define __NR___getcwd __NR_getcwd +static inline _syscall2(int, __getcwd, char *, buf, unsigned long, size); +char *getcwd(char *buf, int size) +{ + int olderrno, ret; + char *allocbuf; + + if (size == 0) { + __set_errno(EINVAL); + return NULL; + } + if (size < 3) { + __set_errno(ERANGE); + return NULL; + } + allocbuf=NULL; + olderrno = errno; + if (buf == NULL) { + buf = allocbuf = malloc (size); + if (buf == NULL) + return NULL; + } + ret = __getcwd(buf, size); + if (ret < 0) { + if (allocbuf) { + free(allocbuf); + } + return NULL; + } + __set_errno(olderrno); + return buf; +} +#else + +/* If the syscall is not present, we have to walk up the + * directory tree till we hit the root. Now we _could_ + * use /proc/self/cwd if /proc is mounted... That approach + * is left an an exercise for the reader... */ + + +/* Seems a few broken filesystems (like coda) don't like this */ /* #undef FAST_DIR_SEARCH_POSSIBLE on Linux */ + /* Routine to find the step back down */ static char *search_dir(dev_t this_dev, ino_t this_ino, char *path_buf, int path_size) { diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c index 542ec1b96..db17d045d 100644 --- a/libc/sysdeps/linux/common/syscalls.c +++ b/libc/sysdeps/linux/common/syscalls.c @@ -1613,13 +1613,7 @@ _syscall3(int, chown, const char *, path, uid_t, owner, gid_t, group); #endif //#define __NR_getcwd 183 -#ifdef L_getcwd -# ifdef __NR_getcwd - _syscall2(int, getcwd, char *, buf, unsigned long, size); -# else -// See unistd/getcwd.c if this syscall is not available... -# endif -#endif +// See getcwd.c in this directory //#define __NR_capget 184 #ifdef L_capget diff --git a/libc/unistd/Makefile b/libc/unistd/Makefile index ee340214d..fbb35fbe5 100644 --- a/libc/unistd/Makefile +++ b/libc/unistd/Makefile @@ -25,7 +25,7 @@ TOPDIR=../../ include $(TOPDIR)Rules.mak DIRS:= -CSRC=execl.c execlp.c execv.c execvep.c execvp.c execle.c getcwd.c \ +CSRC=execl.c execlp.c execv.c execvep.c execvp.c execle.c \ sleep.c usleep.c getpass.c sysconf_src.c getlogin.c \ fpathconf.c confstr.c pathconf.c swab.c usershell.c ifeq ($(strip $(HAS_MMU)),true) |