address two performance issues in do_realpath():

• avoid calling realloc twice in sequence, since the final
  size is known at the first call already
• do not lstat(2) the same path twice in the Hurd codepath
This commit is contained in:
tg 2010-04-27 21:39:09 +00:00
parent 5abce90817
commit 01a0d1104a
3 changed files with 22 additions and 28 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.374 2010/04/20 09:10:05 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.375 2010/04/27 21:39:06 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -25,7 +25,7 @@
# http://www.research.att.com/~gsf/public/ifs.sh # http://www.research.att.com/~gsf/public/ifs.sh
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R39 2010/04/20 @(#)MIRBSD KSH R39 2010/04/27
description: description:
Check version of shell. Check version of shell.
stdin: stdin:

42
funcs.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.154 2010/04/09 18:59:29 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.155 2010/04/27 21:39:08 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -187,6 +187,14 @@ do_realpath(const char *upath)
int symlinks = 32; /* max. recursion depth */ int symlinks = 32; /* max. recursion depth */
int llen; int llen;
struct stat sb; struct stat sb;
#ifdef NO_PATH_MAX
size_t ldestlen = 0;
#define pathlen sb.st_size
#define pathcnd (ldestlen < (pathlen + 1))
#else
#define pathlen PATH_MAX
#define pathcnd (!ldest)
#endif
if (upath[0] == '/') { if (upath[0] == '/') {
/* upath is an absolute pathname */ /* upath is an absolute pathname */
@ -231,11 +239,11 @@ do_realpath(const char *upath)
/* store output position away, then append slash to output */ /* store output position away, then append slash to output */
pos = Xsavepos(xs, xp); pos = Xsavepos(xs, xp);
Xcheck(xs, xp); /* 1 for the '/' and len + 1 for tp and the NUL from below */
XcheckN(xs, xp, 1 + len + 1);
Xput(xs, xp, '/'); Xput(xs, xp, '/');
/* append next pathname component to output */ /* append next pathname component to output */
XcheckN(xs, xp, len + 1);
memcpy(xp, tp, len); memcpy(xp, tp, len);
xp += len; xp += len;
*xp = '\0'; *xp = '\0';
@ -268,29 +276,12 @@ do_realpath(const char *upath)
} }
/* get symlink(7) target */ /* get symlink(7) target */
#ifdef NO_PATH_MAX if (pathcnd)
if (ldest) { ldest = aresize(ldest, pathlen + 1, ATEMP);
afree(ldest, ATEMP); llen = readlink(Xstring(xs, xp), ldest, pathlen);
ldest = NULL; if (llen < 0)
}
{
struct stat hurd_sb;
if (lstat(Xstring(xs, xp), &hurd_sb))
goto notfound;
ldest = alloc(hurd_sb.st_size + 1, ATEMP);
if ((llen = readlink(Xstring(xs, xp), ldest,
hurd_sb.st_size)) < 0)
goto notfound;
}
#else
if (!ldest)
ldest = alloc(PATH_MAX + 1, ATEMP);
if ((llen = readlink(Xstring(xs, xp), ldest,
PATH_MAX)) < 0)
/* oops... */ /* oops... */
goto notfound; goto notfound;
#endif
ldest[llen] = '\0'; ldest[llen] = '\0';
/* /*
@ -331,6 +322,9 @@ do_realpath(const char *upath)
Xfree(xs, xp); Xfree(xs, xp);
errno = llen; errno = llen;
return (NULL); return (NULL);
#undef pathlen
#undef pathcnd
} }
int int

4
sh.h
View File

@ -150,9 +150,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.389 2010/04/20 09:10:07 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.390 2010/04/27 21:39:09 tg Exp $");
#endif #endif
#define MKSH_VERSION "R39 2010/04/20" #define MKSH_VERSION "R39 2010/04/27"
#ifndef MKSH_INCLUDES_ONLY #ifndef MKSH_INCLUDES_ONLY