OSDN Git Service

Cleanup the getcwd implementation (again) since I broke it
authorEric Andersen <andersen@codepoet.org>
Tue, 18 Jun 2002 20:43:49 +0000 (20:43 -0000)
committerEric Andersen <andersen@codepoet.org>
Tue, 18 Jun 2002 20:43:49 +0000 (20:43 -0000)
last night.  Restore malloc-ing when buf=NULL for the syscall
version...  Move getcwd to libc/sysdeps/linux/common and out
of syscalls.c so there is just one getcwd.o object present.
 -Erik

libc/sysdeps/linux/common/Makefile
libc/sysdeps/linux/common/getcwd.c [moved from libc/unistd/getcwd.c with 73% similarity]
libc/sysdeps/linux/common/syscalls.c
libc/unistd/Makefile

index e3098f4..a7a254c 100644 (file)
@@ -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 \
similarity index 73%
rename from libc/unistd/getcwd.c
rename to libc/sysdeps/linux/common/getcwd.c
index fd1e294..1ec00a3 100644 (file)
@@ -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)
 {
index 542ec1b..db17d04 100644 (file)
@@ -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
index ee34021..fbb35fb 100644 (file)
@@ -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)