 84d9c625bf
			
		
	
	
		84d9c625bf
		
	
	
	
	
		
			
			- Fix for possible unset uid/gid in toproto
 - Fix for default mtree style
 - Update libelf
 - Importing libexecinfo
 - Resynchronize GCC, mpc, gmp, mpfr
 - build.sh: Replace params with show-params.
     This has been done as the make target has been renamed in the same
     way, while a new target named params has been added. This new
     target generates a file containing all the parameters, instead of
     printing it on the console.
 - Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org)
     get getservbyport() out of the inner loop
Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
		
	
			
		
			
				
	
	
		
			143 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*	getcwd() - get the name of the current working directory.
 | |
|  *							Author: Kees J. Bot
 | |
|  *								30 Apr 1989
 | |
|  */
 | |
| 
 | |
| #include <sys/cdefs.h>
 | |
| #include "namespace.h"
 | |
| 
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include <errno.h>
 | |
| #include <unistd.h>
 | |
| #include <dirent.h>
 | |
| #include <limits.h>
 | |
| #include <string.h>
 | |
| 
 | |
| /* libc-private interface */
 | |
| int __getcwd(char *, size_t);
 | |
| 
 | |
| static int addpath(const char *path, char **ap, const char *entry)
 | |
| /* Add the name of a directory entry at the front of the path being built.
 | |
|  * Note that the result always starts with a slash.
 | |
|  */
 | |
| {
 | |
| 	const char *e= entry;
 | |
| 	char *p= *ap;
 | |
| 
 | |
| 	while (*e != 0) e++;
 | |
| 
 | |
| 	while (e > entry && p > path) *--p = *--e;
 | |
| 
 | |
| 	if (p == path) return -1;
 | |
| 	*--p = '/';
 | |
| 	*ap= p;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int recover(char *p)
 | |
| /* Undo all those chdir("..")'s that have been recorded by addpath.  This
 | |
|  * has to be done entry by entry, because the whole pathname may be too long.
 | |
|  */
 | |
| {
 | |
| 	int e= errno, slash;
 | |
| 	char *p0;
 | |
| 
 | |
| 	while (*p != 0) {
 | |
| 		p0= ++p;
 | |
| 
 | |
| 		do p++; while (*p != 0 && *p != '/');
 | |
| 		slash= *p; *p= 0;
 | |
| 
 | |
| 		if (chdir(p0) < 0) return -1;
 | |
| 		*p= slash;
 | |
| 	}
 | |
| 	errno= e;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int __getcwd(char *path, size_t size)
 | |
| {
 | |
| 	struct stat above, current, tmp;
 | |
| 	struct dirent *entry;
 | |
| 	DIR *d;
 | |
| 	char *p, *up;
 | |
| 	const char *dotdot = "..";
 | |
| 	int cycle;
 | |
| 
 | |
| 	if (path == NULL || size <= 1) { errno= EINVAL; return -1; }
 | |
| 
 | |
| 	p= path + size;
 | |
| 	*--p = 0;
 | |
| 
 | |
| 	if (stat(".", ¤t) < 0) return -1;
 | |
| 
 | |
| 	while (1) {
 | |
| 		if (stat(dotdot, &above) < 0) { recover(p); return -1; }
 | |
| 
 | |
| 		if (above.st_dev == current.st_dev
 | |
| 					&& above.st_ino == current.st_ino)
 | |
| 			break;	/* Root dir found */
 | |
| 
 | |
| 		if ((d= opendir(dotdot)) == NULL) { recover(p); return -1; }
 | |
| 
 | |
| 		/* Cycle is 0 for a simple inode nr search, or 1 for a search
 | |
| 		 * for inode *and* device nr.
 | |
| 		 */
 | |
| 		cycle= above.st_dev == current.st_dev ? 0 : 1;
 | |
| 
 | |
| 		do {
 | |
| 			char name[3 + NAME_MAX + 1];
 | |
| 
 | |
| 			tmp.st_ino= 0;
 | |
| 			if ((entry= readdir(d)) == NULL) {
 | |
| 				switch (++cycle) {
 | |
| 				case 1:
 | |
| 					rewinddir(d);
 | |
| 					continue;
 | |
| 				case 2:
 | |
| 					closedir(d);
 | |
| 					errno= ENOENT;
 | |
| 					recover(p);
 | |
| 					return -1;
 | |
| 				}
 | |
| 			}
 | |
| 			if (strcmp(entry->d_name, ".") == 0) continue;
 | |
| 			if (strcmp(entry->d_name, "..") == 0) continue;
 | |
| 
 | |
| 			switch (cycle) {
 | |
| 			case 0:
 | |
| 				/* Simple test on inode nr. */
 | |
| 				if (entry->d_ino != current.st_ino) continue;
 | |
| 				/*FALL THROUGH*/
 | |
| 
 | |
| 			case 1:
 | |
| 				/* Current is mounted. */
 | |
| 				strcpy(name, "../");
 | |
| 				strcpy(name+3, entry->d_name);
 | |
| 				if (stat(name, &tmp) < 0) continue;
 | |
| 				break;
 | |
| 			}
 | |
| 		} while (tmp.st_ino != current.st_ino
 | |
| 					|| tmp.st_dev != current.st_dev);
 | |
| 
 | |
| 		up= p;
 | |
| 		if (addpath(path, &up, entry->d_name) < 0) {
 | |
| 			closedir(d);
 | |
| 			errno = ERANGE;
 | |
| 			recover(p);
 | |
| 			return -1;
 | |
| 		}
 | |
| 		closedir(d);
 | |
| 
 | |
| 		if (chdir(dotdot) < 0) { recover(p); return -1; }
 | |
| 		p= up;
 | |
| 
 | |
| 		current= above;
 | |
| 	}
 | |
| 	if (recover(p) < 0) return -1;	/* Undo all those chdir("..")'s. */
 | |
| 	if (*p == 0) *--p = '/';	/* Cwd is "/" if nothing added */
 | |
| 	if (p > path) strcpy(path, p);	/* Move string to start of path. */
 | |
| 	return 0;
 | |
| }
 |