[BusyBox] integrate simplifi_path to shells

Vladimir N. Oleynik dzo at simtreas.ru
Fri Aug 17 02:26:29 UTC 2001


Hi,

I have tried to integrate new function simplify_path from libbb to all busybox
shells 
and have received a prize in 660 bytes for ash and a new opportunity to work 
with symlinks for shell builtins pwd and cmdedit not resolveded them.
If it is interesting, look last patch. 

Something at us has absolutely calmed down... ;)


--w
vodz
-------------- next part --------------
diff -rbu busybox.orig/ash.c busybox/ash.c
--- busybox.orig/ash.c	Thu Aug 16 20:51:47 2001
+++ busybox/ash.c	Thu Aug 16 19:23:04 2001
@@ -1581,9 +1581,7 @@
 static int helpcmd (int, char **);
 static int jobscmd (int, char **);
 static int localcmd (int, char **);
-#ifndef BB_PWD
 static int pwdcmd (int, char **);
-#endif
 static int readcmd (int, char **);
 static int returncmd (int, char **);
 static int setcmd (int, char **);
@@ -1678,9 +1676,7 @@
 	{ BUILTIN_REGULAR    "let", letcmd },
 #endif
 	{ BUILTIN_ASSIGN    "local", localcmd },
-#ifndef BB_PWD
 	{ BUILTIN_NOSPEC    "pwd", pwdcmd },
-#endif
 	{ BUILTIN_REGULAR   "read", readcmd },
 	{ BUILTIN_SPEC_ASSG "readonly", exportcmd },
 	{ BUILTIN_SPECIAL   "return", returncmd },
@@ -1761,15 +1757,12 @@
 static int waitforjob (struct job *);
 
 static int docd (char *, int);
-static char *getcomponent (void);
 static void updatepwd (const char *);
 static void getpwd (void);
 
 static char *padvance (const char **, const char *);
 
 static char nullstr[1];         /* zero length string */
-static char *curdir = nullstr;          /* current working directory */
-static char *cdcomppath;
 
 static int
 cdcmd(argc, argv)
@@ -1790,7 +1783,7 @@
 	if (dest[0] == '-' && dest[1] == '\0') {
 		dest = bltinlookup("OLDPWD");
 		if (!dest || !*dest) {
-			dest = curdir;
+			dest = cwd;
 		}
 		print = 1;
 		if (dest)
@@ -1826,93 +1819,24 @@
  */
 
 static int
-docd(dest, print)
-	char *dest;
-	int print;
+docd(char *dest, int print)
 {
-	char *p;
-	char *q;
-	char *component;
-	struct stat statb;
-	int first;
-	int badstat;
-
 	TRACE(("docd(\"%s\", %d) called\n", dest, print));
-
-	/*
-	 *  Check each component of the path. If we find a symlink or
-	 *  something we can't stat, clear curdir to force a getcwd()
-	 *  next time we get the value of the current directory.
-	 */
-	badstat = 0;
-	cdcomppath = sstrdup(dest);
-	STARTSTACKSTR(p);
-	if (*dest == '/') {
-		STPUTC('/', p);
-		cdcomppath++;
-	}
-	first = 1;
-	while ((q = getcomponent()) != NULL) {
-		if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
-			continue;
-		if (! first)
-			STPUTC('/', p);
-		first = 0;
-		component = q;
-		while (*q)
-			STPUTC(*q++, p);
-		if (equal(component, ".."))
-			continue;
-		STACKSTRNUL(p);
-		if ((lstat(stackblock(), &statb) < 0)
-		    || (S_ISLNK(statb.st_mode)))  {
-			/* print = 1; */
-			badstat = 1;
-			break;
-		}
-	}
-
 	INTOFF;
 	if (chdir(dest) < 0) {
 		INTON;
 		return -1;
 	}
-	updatepwd(badstat ? NULL : dest);
+	updatepwd(dest);
 	INTON;
 	if (print && iflag)
-		printf(snlfmt, curdir);
+		printf(snlfmt, cwd);
 	return 0;
 }
 
 
 /*
- * Get the next component of the path name pointed to by cdcomppath.
- * This routine overwrites the string pointed to by cdcomppath.
- */
-
-static char *
-getcomponent() {
-	char *p;
-	char *start;
-
-	if ((p = cdcomppath) == NULL)
-		return NULL;
-	start = cdcomppath;
-	while (*p != '/' && *p != '\0')
-		p++;
-	if (*p == '\0') {
-		cdcomppath = NULL;
-	} else {
-		*p++ = '\0';
-		cdcomppath = p;
-	}
-	return start;
-}
-
-
-
-/*
- * Update curdir (the name of the current directory) in response to a
+ * Update cwd (the name of the current directory) in response to a
  * cd command.  We also call hashcd to let the routines in exec.c know
  * that the current directory has changed.
  */
@@ -1922,88 +1846,58 @@
 static void
 updatepwd(const char *dir)
 {
-	char *new;
-	char *p;
-	size_t len;
-
 	hashcd();                               /* update command hash table */
 
 	/*
 	 * If our argument is NULL, we don't know the current directory
-	 * any more because we traversed a symbolic link or something
-	 * we couldn't stat().
 	 */
-	if (dir == NULL || curdir == nullstr)  {
+	if (dir == NULL || cwd == unknown)  {
 		setpwd(0, 1);
 		return;
 	}
-	len = strlen(dir);
-	cdcomppath = sstrdup(dir);
-	STARTSTACKSTR(new);
-	if (*dir != '/') {
-		p = curdir;
-		while (*p)
-			STPUTC(*p++, new);
-		if (p[-1] == '/')
-			STUNPUTC(new);
-	}
-	while ((p = getcomponent()) != NULL) {
-		if (equal(p, "..")) {
-			while (new > stackblock() && (STUNPUTC(new), *new) != '/');
-		} else if (*p != '\0' && ! equal(p, ".")) {
-			STPUTC('/', new);
-			while (*p)
-				STPUTC(*p++, new);
-		}
-	}
-	if (new == stackblock())
-		STPUTC('/', new);
-	STACKSTRNUL(new);
-	setpwd(stackblock(), 1);
+	setpwd(dir, 1);
 }
 
 
-#ifndef BB_PWD
 static int
-pwdcmd(argc, argv)
-	int argc;
-	char **argv;
+pwdcmd(int argc, char **argv)
 {
-	printf(snlfmt, curdir);
+	printf(snlfmt, cwd);
 	return 0;
 }
-#endif
 
 /*
- * Find out what the current directory is. If we already know the current
- * directory, this routine returns immediately.
+ * Ask system of current directory
  */
 static void
 getpwd(void)
 {
-	curdir = xgetcwd(0);
-	if(curdir==0)
-		curdir = nullstr;
+	cwd = xgetcwd(0);
+	if(cwd==0)
+		cwd = (char *)unknown;
 }
 
 static void
 setpwd(const char *val, int setold)
 {
+	char *cated = NULL;
+
 	if (setold) {
-		setvar("OLDPWD", curdir, VEXPORT);
+		setvar("OLDPWD", cwd, VEXPORT);
 	}
 	INTOFF;
-	if (curdir != nullstr) {
-		free(curdir);
-		curdir = nullstr;
+	if (cwd!=unknown) {
+		if(val!=NULL && *val != '/')
+			val = cated = concat_path_file(cwd, val);
+		free(cwd);
 	}
-	if (!val) {
+	if (!val)
 		getpwd();
-	} else {
-		curdir = savestr(val);
-	}
+	 else
+		cwd = simplify_path(val);
+	free(cated);
 	INTON;
-	setvar("PWD", curdir, VEXPORT);
+	setvar("PWD", cwd, VEXPORT);
 }
 
 /*
@@ -5980,6 +5874,7 @@
 
       /* from cd.c: */
       {
+	      cwd = (char *)unknown;
 	      setpwd(0, 0);
       }
 
diff -rbu busybox.orig/cmdedit.c busybox/cmdedit.c
--- busybox.orig/cmdedit.c	Fri Aug 17 12:01:15 2001
+++ busybox/cmdedit.c	Fri Aug 17 12:00:36 2001
@@ -335,7 +335,7 @@
 	int sub_len = 0;
 	char  flg_not_length = '[';
 	char *prmt_mem_ptr = xcalloc(1, 1);
-	char *pwd_buf = xgetcwd(0);
+	char *pwd_buf = cwd;
 	char  buf2[PATH_MAX + 1];
 	char  buf[2];
 	char  c;
@@ -442,8 +442,6 @@
 		if (flg_not_length == ']')
 			sub_len++;
 	}
-	if(pwd_buf!=(char *)unknown)
-		free(pwd_buf);
 	cmdedit_prompt = prmt_mem_ptr;
 	cmdedit_prmt_len = prmt_len - sub_len;
 	put_prompt();
@@ -1139,7 +1137,6 @@
 	DEL = 127,
 };
 
-
 /*
  * This function is used to grab a character buffer
  * from the input file descriptor and allows you to
diff -rbu busybox.orig/hush.c busybox/hush.c
--- busybox.orig/hush.c	Thu Aug 16 21:01:51 2001
+++ busybox/hush.c	Fri Aug 17 12:09:37 2001
@@ -243,7 +243,6 @@
 static int fake_mode;
 static int interactive;
 static struct close_me *close_me_head;
-static const char *cwd;
 static struct pipe *job_list;
 static unsigned int last_bg_pid;
 static unsigned int last_jobid;
@@ -425,21 +424,12 @@
 	{NULL, NULL, NULL}
 };
 
-static const char *set_cwd(void)
-{
-	if(cwd==unknown)
-		cwd = NULL;     /* xgetcwd(arg) called free(arg) */
-	cwd = xgetcwd((char *)cwd);
-	if (!cwd)
-		cwd = unknown;
-	return cwd;
-}
-
-
 /* built-in 'cd <path>' handler */
 static int builtin_cd(struct child_prog *child)
 {
 	char *newdir;
+	char *cated = NULL;
+
 	if (child->argv[1] == NULL)
 		newdir = getenv("HOME");
 	else
@@ -448,7 +438,13 @@
 		printf("cd: %s: %s\n", newdir, strerror(errno));
 		return EXIT_FAILURE;
 	}
-	set_cwd();
+	if (cwd!=unknown) {
+		if(*newdir != '/')
+			newdir = cated = concat_path_file(cwd, newdir);
+		free(cwd);
+	}
+	cwd = simplify_path(newdir);
+	free(cated);
 	return EXIT_SUCCESS;
 }
 
@@ -621,7 +617,7 @@
 /* built-in 'pwd' handler */
 static int builtin_pwd(struct child_prog *dummy)
 {
-	puts(set_cwd());
+	puts(cwd);
 	return EXIT_SUCCESS;
 }
 
@@ -2585,7 +2581,9 @@
 	last_jobid = 0;
 
 	/* Initialize some more globals to non-zero values */
-	set_cwd();
+	cwd = xgetcwd(cwd);
+	if (!cwd)
+		cwd = (char *)unknown;
 #ifdef BB_FEATURE_COMMAND_EDITING
 	cmdedit_set_initial_prompt();
 #else
@@ -2673,7 +2671,7 @@
 #ifdef BB_FEATURE_CLEAN_UP
 	fclose(input);
 	if (cwd && cwd != unknown)
-		free((char*)cwd);
+		free(cwd);
 	{
 		struct variables *cur, *tmp;
 		for(cur = top_vars; cur; cur = tmp) {
diff -rbu busybox.orig/lash.c busybox/lash.c
--- busybox.orig/lash.c	Thu Aug 16 21:02:03 2001
+++ busybox/lash.c	Thu Aug 16 19:04:51 2001
@@ -172,9 +172,7 @@
 
 static int shell_context;  /* Type prompt trigger (PS1 or PS2) */
 
-
 /* Globals that are static to this file */
-static const char *cwd;
 static char *local_pending_command = NULL;
 static struct jobset job_list = { NULL, NULL };
 static int argc;
@@ -233,6 +231,7 @@
 static int builtin_cd(struct child_prog *child)
 {
 	char *newdir;
+	char *cated = NULL;
 
 	if (child->argv[1] == NULL)
 		newdir = getenv("HOME");
@@ -242,9 +241,13 @@
 		printf("cd: %s: %m\n", newdir);
 		return EXIT_FAILURE;
 	}
-	cwd = xgetcwd((char *)cwd);
-	if (!cwd)
-		cwd = unknown;
+	if (cwd!=unknown) {
+		if(*newdir != '/')
+			newdir = cated = concat_path_file(cwd, newdir);
+		free(cwd);
+	}
+	cwd = simplify_path(newdir);
+	free(cated);
 	return EXIT_SUCCESS;
 }
 
@@ -367,9 +370,6 @@
 /* built-in 'pwd' handler */
 static int builtin_pwd(struct child_prog *dummy)
 {
-	cwd = xgetcwd((char *)cwd);
-	if (!cwd)
-		cwd = unknown;
 	puts(cwd);
 	return EXIT_SUCCESS;
 }
@@ -1507,15 +1507,15 @@
 #ifdef BB_FEATURE_CLEAN_UP
 void free_memory(void)
 {
-	if (cwd) {
+	if (cwd!=unknown)
 		free(cwd);
-	}
+
 	if (local_pending_command)
 		free(local_pending_command);
 
-	if (job_list.fg && !job_list.fg->running_progs) {
+	if (job_list.fg && !job_list.fg->running_progs)
 		remove_job(&job_list, job_list.fg);
-	}
+
 }
 #endif
 
@@ -1560,6 +1560,11 @@
 	job_list.fg = NULL;
 	last_return_code=1;
 
+	/* initialize the cwd */
+	cwd = xgetcwd(0);
+	if (!cwd)
+		cwd = (char *)unknown;
+
 	if (argv[0] && argv[0][0] == '-') {
 		FILE *prof_input;
 		prof_input = fopen("/etc/profile", "r");
@@ -1612,11 +1617,6 @@
 		input = xfopen(argv[optind], "r");
 		mark_open(fileno(input));  /* be lazy, never mark this closed */
 	}
-
-	/* initialize the cwd -- this is never freed...*/
-	cwd = xgetcwd(0);
-	if (!cwd)
-		cwd = unknown;
 
 #ifdef BB_FEATURE_CLEAN_UP
 	atexit(free_memory);
diff -rbu busybox.orig/libbb/libbb.h busybox/libbb/libbb.h
--- busybox.orig/libbb/libbb.h	Thu Aug 16 20:58:31 2001
+++ busybox/libbb/libbb.h	Fri Aug 17 12:07:02 2001
@@ -210,6 +210,7 @@
 int klogctl(int type, char * b, int len);
 
 char *xgetcwd(char *cwd);
+extern char *cwd;       /* set in shells */
 char *xreadlink(const char *path);
 char *concat_path_file(const char *path, const char *filename);
 char *last_char_is(const char *s, int c);
diff -rbu busybox.orig/libbb/xgetcwd.c busybox/libbb/xgetcwd.c
--- busybox.orig/libbb/xgetcwd.c	Thu Aug 16 21:00:20 2001
+++ busybox/libbb/xgetcwd.c	Thu Aug 16 18:47:44 2001
@@ -20,8 +20,11 @@
    If argument is not NULL (previous usage allocate memory), call free()
 */
 
+/* global variable */
+char *cwd;
+
 char *
-xgetcwd (char *cwd)
+xgetcwd (char *arg_cwd)
 {
   char *ret;
   unsigned path_max;
@@ -30,8 +33,10 @@
   path_max = (unsigned) PATH_MAX;
   path_max += 2;                /* The getcwd docs say to do this. */
 
-  if(cwd==0)
+  if(arg_cwd==NULL)
 	cwd = xmalloc (path_max);
+   else
+	cwd = arg_cwd;
 
   errno = 0;
   while ((ret = getcwd (cwd, path_max)) == NULL && errno == ERANGE) {
@@ -43,9 +48,9 @@
   if (ret == NULL) {
       int save_errno = errno;
       free (cwd);
+      cwd = NULL;
       errno = save_errno;
       perror_msg("getcwd()");
-      return NULL;
   }
 
   return cwd;
diff -rbu busybox.orig/tar.c busybox/tar.c
--- busybox.orig/tar.c	Thu Aug 16 20:57:49 2001
+++ busybox/tar.c	Thu Aug 16 18:48:25 2001
@@ -151,7 +151,7 @@
 	char** excludeList=NULL;
 	char** extractList=NULL;
 	const char *tarName="-";
-	const char *cwd=NULL;
+
 #if defined BB_FEATURE_TAR_EXCLUDE
 	int excludeListSize=0;
 	FILE *fileList;
@@ -242,7 +242,7 @@
 			case 'p':
 				break;
 			case 'C':
-				cwd = xgetcwd((char *)cwd);
+				cwd = xgetcwd(cwd);
 				if (chdir(optarg)) {
 					printf("cd: %s: %s\n", optarg, strerror(errno));
 					return EXIT_FAILURE;


More information about the busybox mailing list