summaryrefslogtreecommitdiff
path: root/libc/unistd/getcwd.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-06-18 20:43:49 +0000
committerEric Andersen <andersen@codepoet.org>2002-06-18 20:43:49 +0000
commitb8d09d7cfc7a5aec2d510335313c0e5470df37c1 (patch)
treefbaa1970c2c6b02ed099f0b7f760a2e4b5a6226c /libc/unistd/getcwd.c
parenta27edd5fc9ef34a3d8c61397d2253817336d2a9c (diff)
Cleanup the getcwd implementation (again) since I broke it
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
Diffstat (limited to 'libc/unistd/getcwd.c')
-rw-r--r--libc/unistd/getcwd.c131
1 files changed, 0 insertions, 131 deletions
diff --git a/libc/unistd/getcwd.c b/libc/unistd/getcwd.c
deleted file mode 100644
index fd1e29445..000000000
--- a/libc/unistd/getcwd.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* These functions find the absolute path to the current working directory. */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <string.h>
-#include <sys/syscall.h>
-
-/* if the syscall is not present, we have to recurse up */
-#ifndef __NR_getcwd
-
-/* #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)
-{
- DIR *dp;
- struct dirent *d;
- char *ptr;
- int slen;
- struct stat st;
-
-#ifdef FAST_DIR_SEARCH_POSSIBLE
- /* The test is for ELKS lib 0.0.9, this should be fixed in the real kernel */
- int slow_search = (sizeof(ino_t) != sizeof(d->d_ino));
-#endif
-
- if (stat(path_buf, &st) < 0)
- return 0;
-#ifdef FAST_DIR_SEARCH_POSSIBLE
- if (this_dev != st.st_dev)
- slow_search = 1;
-#endif
-
- slen = strlen(path_buf);
- ptr = path_buf + slen - 1;
- if (*ptr != '/') {
- if (slen + 2 > path_size) {
- __set_errno(ERANGE);
- return 0;
- }
- strcpy(++ptr, "/");
- slen++;
- }
- slen++;
-
- dp = opendir(path_buf);
- if (dp == 0)
- return 0;
-
- while ((d = readdir(dp)) != 0) {
-#ifdef FAST_DIR_SEARCH_POSSIBLE
- if (slow_search || this_ino == d->d_ino) {
-#endif
- if (slen + strlen(d->d_name) > path_size) {
- __set_errno(ERANGE);
- return 0;
- }
- strcpy(ptr + 1, d->d_name);
- if (stat(path_buf, &st) < 0)
- continue;
- if (st.st_ino == this_ino && st.st_dev == this_dev) {
- closedir(dp);
- return path_buf;
- }
-#ifdef FAST_DIR_SEARCH_POSSIBLE
- }
-#endif
- }
-
- closedir(dp);
- __set_errno(ENOENT);
- return 0;
-}
-
-/* Routine to go up tree */
-static char *recurser(char *path_buf, int path_size, dev_t root_dev, ino_t root_ino)
-{
- struct stat st;
- dev_t this_dev;
- ino_t this_ino;
-
- if (stat(path_buf, &st) < 0)
- return 0;
- this_dev = st.st_dev;
- this_ino = st.st_ino;
- if (this_dev == root_dev && this_ino == root_ino) {
- strcpy(path_buf, "/");
- return path_buf;
- }
- if (strlen(path_buf) + 4 > path_size) {
- __set_errno(ERANGE);
- return 0;
- }
- strcat(path_buf, "/..");
- if (recurser(path_buf, path_size, root_dev, root_ino) == 0)
- return 0;
-
- return search_dir(this_dev, this_ino, path_buf, path_size);
-}
-
-
-char *getcwd(char *buf, int size)
-{
- struct stat st;
-
- if (size == 0) {
- __set_errno(EINVAL);
- return NULL;
- }
- if (size < 3) {
- __set_errno(ERANGE);
- return NULL;
- }
-
- if (buf == NULL) {
- buf = malloc (size);
- if (buf == NULL)
- return NULL;
- }
-
- strcpy(buf, ".");
- if (stat("/", &st) < 0) {
- return NULL;
- }
-
- return recurser(buf, size, st.st_dev, st.st_ino);
-}
-
-#endif