[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