summaryrefslogtreecommitdiff
path: root/libc/misc
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1996-12-01 16:58:31 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:34:16 +0200
commitf8de35da65c5d93bb733073cf40da154bc1c0748 (patch)
treed28c7644739a24402376d24cb0020ea410a9ccff /libc/misc
parentc218c617b5be443b7968308506969ad2b726d73c (diff)
downloaddev86-f8de35da65c5d93bb733073cf40da154bc1c0748.tar.gz
Import Dev86src-0.0.9.tar.gzv0.0.9
Diffstat (limited to 'libc/misc')
-rw-r--r--libc/misc/Makefile2
-rw-r--r--libc/misc/ctype.c2
-rw-r--r--libc/misc/getcwd.c109
3 files changed, 111 insertions, 2 deletions
diff --git a/libc/misc/Makefile b/libc/misc/Makefile
index 3db73a7..c7ed8fa 100644
--- a/libc/misc/Makefile
+++ b/libc/misc/Makefile
@@ -15,7 +15,7 @@ GOBJ=atoi.o atol.o ltoa.o ltostr.o \
ctype.o qsort.o bsearch.o rand.o lsearch.o getopt.o \
itoa.o cputype.o strtol.o crypt.o
-UOBJ=getenv.o putenv.o popen.o system.o setenv.o
+UOBJ=getenv.o putenv.o popen.o system.o setenv.o getcwd.o
ifeq ($(LIB_OS),ELKS)
diff --git a/libc/misc/ctype.c b/libc/misc/ctype.c
index 1514668..6b6cd3d 100644
--- a/libc/misc/ctype.c
+++ b/libc/misc/ctype.c
@@ -12,7 +12,7 @@
#undef toupper
#undef tolower
-unsigned char _ctype[128] =
+unsigned char __ctype[128] =
{
__CT_c, __CT_c, __CT_c, __CT_c, /* 0x00..0x03 */
__CT_c, __CT_c, __CT_c, __CT_c, /* 0x04..0x07 */
diff --git a/libc/misc/getcwd.c b/libc/misc/getcwd.c
new file mode 100644
index 0000000..351214c
--- /dev/null
+++ b/libc/misc/getcwd.c
@@ -0,0 +1,109 @@
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <string.h>
+/*
+ * These functions find the absolute path to the current working directory.
+ *
+ * They don't use malloc or large amounts of stack space.
+ */
+
+static char * recurser(); /* Routine to go up tree */
+static char * search_dir(); /* Routine to find the step back down */
+static char * path_buf;
+static int path_size;
+
+static dev_t root_dev;
+static ino_t root_ino;
+
+static struct stat st;
+
+char *
+getcwd(buf, size)
+char * buf;
+int size;
+{
+ path_buf = buf;
+ path_size = size;
+
+ if( size < 3 ) { errno = ERANGE; return 0; }
+ strcpy(path_buf, ".");
+
+ if( stat("/", &st) < 0 ) return 0;
+
+ root_dev = st.st_dev;
+ root_ino = st.st_ino;
+
+ return recurser();
+}
+
+static char *
+recurser()
+{
+ 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 ) { errno = ERANGE; return 0; }
+ strcat(path_buf, "/..");
+ if( recurser() == 0 ) return 0;
+
+ return search_dir(this_dev, this_ino);
+}
+
+static char *
+search_dir(this_dev, this_ino)
+dev_t this_dev;
+ino_t this_ino;
+{
+ DIR * dp;
+ struct dirent * d;
+ char * ptr;
+ int slen;
+ /* 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));
+
+ if( stat(path_buf, &st) < 0 ) return 0;
+ if( this_dev != st.st_dev ) slow_search = 1;
+
+ slen = strlen(path_buf);
+ ptr = path_buf + slen -1;
+ if( *ptr != '/' )
+ {
+ if( slen + 2 > path_size ) { errno = ERANGE; return 0; }
+ strcpy(++ptr, "/");
+ slen++;
+ }
+ slen++;
+
+ dp = opendir(path_buf);
+ if( dp == 0 ) return 0;
+
+ while( (d=readdir(dp)) != 0 )
+ {
+ if( slow_search || this_ino == d->d_ino )
+ {
+ if( slen + strlen(d->d_name) > path_size )
+ { 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;
+ }
+ }
+ }
+
+ closedir(dp);
+ errno = ENOENT;
+ return 0;
+}