mirror of
https://github.com/coreutils/coreutils.git
synced 2024-11-24 10:23:31 +08:00
(xgetcwd): If the required pathname length is smaller
than 1024, return a memory chunk of least possible size, instead of size PATH_MAX + 2. In the loop, increment the size proportionally. Use free/xmalloc instead of xrealloc to avoid copying for very long paths.
This commit is contained in:
parent
0c3c6ef55e
commit
978bf5f750
@ -1,5 +1,5 @@
|
||||
/* xgetcwd.c -- return current directory with unlimited length
|
||||
Copyright (C) 1992, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1996, 2000 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -37,12 +37,9 @@ char *getwd ();
|
||||
# define getcwd(Buf, Max) getwd (Buf)
|
||||
#endif
|
||||
|
||||
/* Amount to increase buffer size by in each try. */
|
||||
#define PATH_INCR 32
|
||||
|
||||
char *xmalloc ();
|
||||
char *xrealloc ();
|
||||
void free ();
|
||||
extern void *xmalloc ();
|
||||
extern char *xstrdup ();
|
||||
extern void free ();
|
||||
|
||||
/* Return the current directory, newly allocated, arbitrarily long.
|
||||
Return NULL and set errno on error. */
|
||||
@ -50,30 +47,39 @@ void free ();
|
||||
char *
|
||||
xgetcwd ()
|
||||
{
|
||||
char *cwd;
|
||||
char *ret;
|
||||
unsigned path_max;
|
||||
char buf[1024];
|
||||
|
||||
errno = 0;
|
||||
ret = getcwd (buf, sizeof (buf));
|
||||
if (ret != NULL)
|
||||
return xstrdup (buf);
|
||||
if (errno != ERANGE)
|
||||
return NULL;
|
||||
|
||||
path_max = (unsigned) PATH_MAX;
|
||||
path_max += 2; /* The getcwd docs say to do this. */
|
||||
|
||||
cwd = xmalloc (path_max);
|
||||
|
||||
errno = 0;
|
||||
while ((ret = getcwd (cwd, path_max)) == NULL && errno == ERANGE)
|
||||
for (;;)
|
||||
{
|
||||
path_max += PATH_INCR;
|
||||
cwd = xrealloc (cwd, path_max);
|
||||
char *cwd = (char *) xmalloc (path_max);
|
||||
|
||||
errno = 0;
|
||||
}
|
||||
ret = getcwd (cwd, path_max);
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
if (errno != ERANGE)
|
||||
{
|
||||
int save_errno = errno;
|
||||
free (cwd);
|
||||
errno = save_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ret == NULL)
|
||||
{
|
||||
int save_errno = errno;
|
||||
free (cwd);
|
||||
errno = save_errno;
|
||||
return NULL;
|
||||
|
||||
path_max += path_max / 16;
|
||||
path_max += 32;
|
||||
}
|
||||
return cwd;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user