Reported by Peter Kruse in
<http://lists.gnu.org/archive/html/bug-tar/2013-10/msg00017.html>.
This doesn't fix all the Solaris 10 test failures, just the core dump.
* src/common.h, src/misc.c (tar_getcdpath): Now static.
* src/misc.c (normalize_filename): Report a fatal error
if cdpath is null, since we don't know the absolute name
of the working directory in that case. FIXME: there should
be no need to know absolute file names.
(chdir_arg): Simplify wd allocation.
Don't assume that xgetcwd returns non-null.
void namebuf_add_dir (namebuf_t buf, const char *name);
char *namebuf_finish (namebuf_t buf);
void namebuf_add_dir (namebuf_t buf, const char *name);
char *namebuf_finish (namebuf_t buf);
-const char *tar_getcdpath (int);
const char *tar_dirname (void);
/* Represent N using a signed integer I such that (uintmax_t) I == N.
const char *tar_dirname (void);
/* Represent N using a signed integer I such that (uintmax_t) I == N.
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
#endif
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
#endif
+static const char *tar_getcdpath (int);
+
\f
/* Handling strings. */
\f
/* Handling strings. */
/* Normalize FILE_NAME by removing redundant slashes and "."
components, including redundant trailing slashes.
/* Normalize FILE_NAME by removing redundant slashes and "."
components, including redundant trailing slashes.
- Leave ".." alone, as it may be significant in the presence
+ Leave ".." alone, as it may be significant in the presence
of symlinks and on platforms where "/.." != "/".
Destructive version: modifies its argument. */
of symlinks and on platforms where "/.." != "/".
Destructive version: modifies its argument. */
const char *cdpath = tar_getcdpath (cdidx);
size_t copylen;
bool need_separator;
const char *cdpath = tar_getcdpath (cdidx);
size_t copylen;
bool need_separator;
+
+ if (!cdpath)
+ call_arg_fatal ("getcwd", ".");
copylen = strlen (cdpath);
need_separator = ! (DOUBLE_SLASH_IS_DISTINCT_ROOT
&& copylen == 2 && ISSLASH (cdpath[1]));
copylen = strlen (cdpath);
need_separator = ! (DOUBLE_SLASH_IS_DISTINCT_ROOT
&& copylen == 2 && ISSLASH (cdpath[1]));
{
/* The directory's name. */
char const *name;
{
/* The directory's name. */
char const *name;
- /* "absolute" path representing this directory; in the contrast to
+ /* "Absolute" path representing this directory; in the contrast to
the real absolute pathname, it can contain /../ components (see
the real absolute pathname, it can contain /../ components (see
- normalize_filename_x for the reason of it). */
- char *abspath;
+ normalize_filename_x for the reason of it). It is NULL if the
+ absolute path could not be determined. */
+ char *abspath;
/* If nonzero, the file descriptor of the directory, or AT_FDCWD if
the working directory. If zero, the directory needs to be opened
to be used. */
/* If nonzero, the file descriptor of the directory, or AT_FDCWD if
the working directory. If zero, the directory needs to be opened
to be used. */
int
chdir_arg (char const *dir)
{
int
chdir_arg (char const *dir)
{
if (wd_count == wd_alloc)
{
if (wd_alloc == 0)
if (wd_count == wd_alloc)
{
if (wd_alloc == 0)
- {
- wd_alloc = 2;
- wd = xmalloc (sizeof *wd * wd_alloc);
- }
- else
- wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
+ wd_alloc = 2;
+ wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
- wd[wd_count].name = dir;
- /* if the given name is an absolute path, then use that path
- to represent this working directory; otherwise, construct
- a path based on the previous -C option's absolute path */
- if (IS_ABSOLUTE_FILE_NAME (wd[wd_count].name))
- wd[wd_count].abspath = xstrdup (wd[wd_count].name);
- else
+
+ /* If the given name is absolute, use it to represent this directory;
+ otherwise, construct a name based on the previous -C option. */
+ if (IS_ABSOLUTE_FILE_NAME (dir))
+ absdir = xstrdup (dir);
+ else if (wd[wd_count - 1].abspath)
{
namebuf_t nbuf = namebuf_create (wd[wd_count - 1].abspath);
{
namebuf_t nbuf = namebuf_create (wd[wd_count - 1].abspath);
- namebuf_add_dir (nbuf, wd[wd_count].name);
- wd[wd_count].abspath = namebuf_finish (nbuf);
+ namebuf_add_dir (nbuf, dir);
+ absdir = namebuf_finish (nbuf);
+ else
+ absdir = 0;
+
+ wd[wd_count].name = dir;
+ wd[wd_count].abspath = absdir;
wd[wd_count].fd = 0;
return wd_count++;
}
wd[wd_count].fd = 0;
return wd_count++;
}
chdir_args() has never been called, so we simply return the
process's actual cwd. (Note that in this case IDX is ignored,
since it should always be 0.) */
chdir_args() has never been called, so we simply return the
process's actual cwd. (Note that in this case IDX is ignored,
since it should always be 0.) */
tar_getcdpath (int idx)
{
if (!wd)
tar_getcdpath (int idx)
{
if (!wd)
namebuf_finish (namebuf_t buf)
{
char *res = buf->buffer;
namebuf_finish (namebuf_t buf)
{
char *res = buf->buffer;
if (ISSLASH (buf->buffer[buf->dir_length - 1]))
buf->buffer[buf->dir_length] = 0;
free (buf);
if (ISSLASH (buf->buffer[buf->dir_length - 1]))
buf->buffer[buf->dir_length] = 0;
free (buf);