mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-27 04:40:59 +01:00
26754: tweak zgetdir() and test for realpath()
This commit is contained in:
parent
9e1a3e6d06
commit
cb6856d115
5 changed files with 69 additions and 8 deletions
|
|
@ -1,3 +1,8 @@
|
|||
2009-03-19 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 26754: configure.ac, Doc/Zsh/expn.yo, Src/compat.c, Src/hist.c:
|
||||
tweak zgetdir() (but don't use it) and test for realpath().
|
||||
|
||||
2009-03-18 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 26752: Src/hist.c: fix ../ removal in :a and metafication
|
||||
|
|
@ -11443,5 +11448,5 @@
|
|||
|
||||
*****************************************************
|
||||
* This is used by the shell to define $ZSH_PATCHLEVEL
|
||||
* $Revision: 1.4624 $
|
||||
* $Revision: 1.4625 $
|
||||
*****************************************************
|
||||
|
|
|
|||
|
|
@ -223,7 +223,8 @@ if necessary, and resolves any use of `tt(..)' and `tt(.)' in the path.
|
|||
item(tt(A))(
|
||||
As `tt(a)', but also resolve use of symbolic links where possible.
|
||||
Note that resolution of `tt(..)' occurs em(before) resolution of symbolic
|
||||
links.
|
||||
links. This call is equivalent to tt(a) unless your system has the
|
||||
tt(realpath) system call (modern systems do).
|
||||
)
|
||||
item(tt(e))(
|
||||
Remove all but the extension.
|
||||
|
|
|
|||
32
Src/compat.c
32
Src/compat.c
|
|
@ -227,6 +227,26 @@ zopenmax(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Rationalise the current directory, returning the string.
|
||||
*
|
||||
* If "d" is not NULL, it is used to store information about the
|
||||
* directory. The returned name is also present in d->dirname and is in
|
||||
* permanently allocated memory. The handling of this case depends on
|
||||
* whether the fchdir() system call is available; if it is, it is assumed
|
||||
* the caller is able to restore the current directory. On successfully
|
||||
* identifying the directory the function returns immediately rather
|
||||
* than ascending the hierarchy.
|
||||
*
|
||||
* If "d" is NULL, no assumption about the caller's behaviour is
|
||||
* made. The returned string is in heap memory. This case is
|
||||
* always handled by changing directory up the hierarchy.
|
||||
*
|
||||
* On Cygwin or other systems where USE_GETCWD is defined (at the
|
||||
* time of writing only QNX), we skip all the above and use the
|
||||
* getcwd() system call.
|
||||
*/
|
||||
|
||||
/**/
|
||||
mod_export char *
|
||||
zgetdir(struct dirsav *d)
|
||||
|
|
@ -257,25 +277,30 @@ zgetdir(struct dirsav *d)
|
|||
return buf;
|
||||
}
|
||||
|
||||
/* Record the initial inode and device */
|
||||
pino = sbuf.st_ino;
|
||||
pdev = sbuf.st_dev;
|
||||
if (d)
|
||||
d->ino = pino, d->dev = pdev;
|
||||
#if !defined(__CYGWIN__) && !defined(USE_GETCWD)
|
||||
#ifdef HAVE_FCHDIR
|
||||
else
|
||||
#endif
|
||||
#if !defined(__CYGWIN__) && !defined(USE_GETCWD)
|
||||
holdintr();
|
||||
|
||||
for (;;) {
|
||||
/* Examine the parent of the current directory. */
|
||||
if (stat("..", &sbuf) < 0)
|
||||
break;
|
||||
|
||||
/* Inode and device of curtent directory */
|
||||
ino = pino;
|
||||
dev = pdev;
|
||||
/* Inode and device of current directory's parent */
|
||||
pino = sbuf.st_ino;
|
||||
pdev = sbuf.st_dev;
|
||||
|
||||
/* If they're the same, we've reached the root directory. */
|
||||
if (ino == pino && dev == pdev) {
|
||||
if (!buf[pos])
|
||||
buf[--pos] = '/';
|
||||
|
|
@ -291,6 +316,7 @@ zgetdir(struct dirsav *d)
|
|||
return buf + pos;
|
||||
}
|
||||
|
||||
/* Search the parent for the current directory. */
|
||||
if (!(dir = opendir("..")))
|
||||
break;
|
||||
|
||||
|
|
@ -303,6 +329,7 @@ zgetdir(struct dirsav *d)
|
|||
continue;
|
||||
#ifdef HAVE_STRUCT_DIRENT_D_STAT
|
||||
if(de->d_stat.st_dev == dev && de->d_stat.st_ino == ino) {
|
||||
/* Found the directory we're currently in */
|
||||
strncpy(nbuf + 3, fn, PATH_MAX);
|
||||
break;
|
||||
}
|
||||
|
|
@ -311,6 +338,7 @@ zgetdir(struct dirsav *d)
|
|||
if (dev != pdev || (ino_t) de->d_ino == ino)
|
||||
# endif /* HAVE_STRUCT_DIRENT_D_INO */
|
||||
{
|
||||
/* Maybe found directory, need to check device & inode */
|
||||
strncpy(nbuf + 3, fn, PATH_MAX);
|
||||
lstat(nbuf, &sbuf);
|
||||
if (sbuf.st_dev == dev && sbuf.st_ino == ino)
|
||||
|
|
@ -320,7 +348,7 @@ zgetdir(struct dirsav *d)
|
|||
}
|
||||
closedir(dir);
|
||||
if (!de)
|
||||
break;
|
||||
break; /* Not found */
|
||||
len = strlen(nbuf + 2);
|
||||
pos -= len;
|
||||
while (pos <= 1) {
|
||||
|
|
|
|||
30
Src/hist.c
30
Src/hist.c
|
|
@ -1579,7 +1579,14 @@ chabspath(char **junkptr)
|
|||
int
|
||||
chrealpath(char **junkptr)
|
||||
{
|
||||
char *str;
|
||||
#ifdef HAVE_CANONICALIZE_FILE_NAME
|
||||
char *lastpos, *nonreal, *real;
|
||||
#else
|
||||
# ifdef HAVE_REAL_PATH
|
||||
char *lastpos, *nonreal, real[PATH_MAX];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (!**junkptr)
|
||||
return 1;
|
||||
|
|
@ -1588,6 +1595,9 @@ chrealpath(char **junkptr)
|
|||
if (!chabspath(junkptr))
|
||||
return 0;
|
||||
|
||||
#if !defined(HAVE_REALPATH) && !defined(HAVE_CANONICALIZE_FILE_NAME)
|
||||
return 1;
|
||||
#else
|
||||
/*
|
||||
* Notice that this means you cannot pass relative paths into this
|
||||
* function!
|
||||
|
|
@ -1600,7 +1610,19 @@ chrealpath(char **junkptr)
|
|||
lastpos = strend(*junkptr);
|
||||
nonreal = lastpos + 1;
|
||||
|
||||
while (!realpath(*junkptr, real)) {
|
||||
while (!
|
||||
#ifdef HAVE_CANONICALIZE_FILE_NAME
|
||||
/*
|
||||
* This is a GNU extension to realpath(); it's the
|
||||
* same as calling realpath() with a NULL second argument
|
||||
* which uses malloc() to get memory. The alternative
|
||||
* interface is easier to test for, however.
|
||||
*/
|
||||
(real = canonicalize_file_name(*junkptr))
|
||||
#else
|
||||
realpath(*junkptr, real)
|
||||
#endif
|
||||
) {
|
||||
if (errno == EINVAL || errno == ELOOP ||
|
||||
errno == ENAMETOOLONG || errno == ENOMEM)
|
||||
return 0;
|
||||
|
|
@ -1615,7 +1637,7 @@ chrealpath(char **junkptr)
|
|||
*nonreal = '\0';
|
||||
}
|
||||
|
||||
char *str = nonreal;
|
||||
str = nonreal;
|
||||
while (str <= lastpos) {
|
||||
if (*str == '\0')
|
||||
*str = '/';
|
||||
|
|
@ -1623,6 +1645,10 @@ chrealpath(char **junkptr)
|
|||
}
|
||||
|
||||
*junkptr = metafy(bicat(real, nonreal), -1, META_HEAPDUP);
|
||||
#ifdef HAVE_CANONICALIZE_FILE_NAME
|
||||
free(real);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1157,7 +1157,8 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
|
|||
grantpt unlockpt ptsname \
|
||||
htons ntohs \
|
||||
regcomp regexec regerror regfree \
|
||||
gdbm_open getxattr)
|
||||
gdbm_open getxattr \
|
||||
realpath canonicalize_file_name)
|
||||
AC_FUNC_STRCOLL
|
||||
|
||||
if test x$enable_cap = xyes; then
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue