/* Diff files from a tar archive.
Copyright 1988, 1992-1994, 1996-1997, 1999-2001, 2003-2007,
- 2009-2010, 2012-2013 Free Software Foundation, Inc.
+ 2009-2010, 2012-2014, 2016 Free Software Foundation, Inc.
This file is part of GNU tar.
static void
diff_symlink (void)
{
+ char buf[1024];
size_t len = strlen (current_stat_info.link_name);
- char *linkbuf = alloca (len + 1);
+ char *linkbuf = len < sizeof buf ? buf : xmalloc (len + 1);
- int status = readlinkat (chdir_fd, current_stat_info.file_name,
- linkbuf, len + 1);
+ ssize_t status = readlinkat (chdir_fd, current_stat_info.file_name,
+ linkbuf, len + 1);
if (status < 0)
{
report_difference (¤t_stat_info, NULL);
}
else if (status != len
- || strncmp (current_stat_info.link_name, linkbuf, len) != 0)
+ || memcmp (current_stat_info.link_name, linkbuf, len) != 0)
report_difference (¤t_stat_info, _("Symlink differs"));
+
+ if (linkbuf != buf)
+ free (linkbuf);
}
#endif
if (fd < 0)
diag = open_diag;
else if (fstat (fd, &dir->stat))
- diag = stat_diag;
+ {
+ diag = stat_diag;
+ close (fd);
+ }
else
dir->fd = fd;
if (diag)
{
seek_error_details (current_stat_info.file_name, offset);
report_difference (¤t_stat_info, NULL);
- return;
}
-
- read_and_process (¤t_stat_info, process_rawdata);
+ else
+ read_and_process (¤t_stat_info, process_rawdata);
status = close (fd);
if (status != 0)