* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / libc / misc / getcwd.c
blob351214cf466d88ccb86e27607683578baeb8454e
2 #include <errno.h>
3 #include <sys/stat.h>
4 #include <dirent.h>
5 #include <string.h>
6 /*
7 * These functions find the absolute path to the current working directory.
9 * They don't use malloc or large amounts of stack space.
12 static char * recurser(); /* Routine to go up tree */
13 static char * search_dir(); /* Routine to find the step back down */
14 static char * path_buf;
15 static int path_size;
17 static dev_t root_dev;
18 static ino_t root_ino;
20 static struct stat st;
22 char *
23 getcwd(buf, size)
24 char * buf;
25 int size;
27 path_buf = buf;
28 path_size = size;
30 if( size < 3 ) { errno = ERANGE; return 0; }
31 strcpy(path_buf, ".");
33 if( stat("/", &st) < 0 ) return 0;
35 root_dev = st.st_dev;
36 root_ino = st.st_ino;
38 return recurser();
41 static char *
42 recurser()
44 dev_t this_dev;
45 ino_t this_ino;
46 if( stat(path_buf, &st) < 0 ) return 0;
47 this_dev = st.st_dev;
48 this_ino = st.st_ino;
49 if( this_dev == root_dev && this_ino == root_ino )
51 strcpy(path_buf, "/");
52 return path_buf;
54 if( strlen(path_buf) + 4 > path_size ) { errno = ERANGE; return 0; }
55 strcat(path_buf, "/..");
56 if( recurser() == 0 ) return 0;
58 return search_dir(this_dev, this_ino);
61 static char *
62 search_dir(this_dev, this_ino)
63 dev_t this_dev;
64 ino_t this_ino;
66 DIR * dp;
67 struct dirent * d;
68 char * ptr;
69 int slen;
70 /* The test is for ELKS lib 0.0.9, this should be fixed in the real kernel*/
71 int slow_search = (sizeof(ino_t) != sizeof(d->d_ino));
73 if( stat(path_buf, &st) < 0 ) return 0;
74 if( this_dev != st.st_dev ) slow_search = 1;
76 slen = strlen(path_buf);
77 ptr = path_buf + slen -1;
78 if( *ptr != '/' )
80 if( slen + 2 > path_size ) { errno = ERANGE; return 0; }
81 strcpy(++ptr, "/");
82 slen++;
84 slen++;
86 dp = opendir(path_buf);
87 if( dp == 0 ) return 0;
89 while( (d=readdir(dp)) != 0 )
91 if( slow_search || this_ino == d->d_ino )
93 if( slen + strlen(d->d_name) > path_size )
94 { errno = ERANGE; return 0; }
95 strcpy(ptr+1, d->d_name);
96 if( stat(path_buf, &st) < 0 )
97 continue;
98 if( st.st_ino == this_ino && st.st_dev == this_dev )
100 closedir(dp);
101 return path_buf;
106 closedir(dp);
107 errno = ENOENT;
108 return 0;