# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
#endif
+static const char *tar_getcdpath (int);
+
\f
/* Handling strings. */
/* 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. */
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]));
{
/* 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
- 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. */
int
chdir_arg (char const *dir)
{
+ char *absdir;
+
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);
if (! wd_count)
{
return wd_count - 1;
}
- 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_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++;
}
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.) */
-const char *
+static const char *
tar_getcdpath (int idx)
{
if (!wd)
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);