]> Dogcows Code - chaz/tar/blobdiff - src/misc.c
tar: quote 'like this', not `like this'
[chaz/tar] / src / misc.c
index 763c661e9ca704d6193633baaa3020628d217110..126161b4a037878f603a6a7299eddea4be10926f 100644 (file)
@@ -37,8 +37,7 @@
 void
 assign_string (char **string, const char *value)
 {
-  if (*string)
-    free (*string);
+  free (*string);
   *string = value ? xstrdup (value) : 0;
 }
 
@@ -106,7 +105,7 @@ quote_copy_string (const char *string)
    completes the unquoting anyway.
 
    This is used for reading the saved directory file in incremental
-   dumps.  It is used for decoding old `N' records (demangling names).
+   dumps.  It is used for decoding old 'N' records (demangling names).
    But also, it is used for decoding file arguments, would they come
    from the shell or a -T file, and for decoding the --exclude
    argument.  */
@@ -617,6 +616,57 @@ deref_stat (char const *name, struct stat *buf)
   return fstatat (chdir_fd, name, buf, fstatat_flags);
 }
 
+/* Read from FD into the buffer BUF with COUNT bytes.  Attempt to fill
+   BUF.  Wait until input is available; this matters because files are
+   opened O_NONBLOCK for security reasons, and on some file systems
+   this can cause read to fail with errno == EAGAIN.  Return the
+   actual number of bytes read, zero for EOF, or
+   SAFE_READ_ERROR upon error.  */
+size_t
+blocking_read (int fd, void *buf, size_t count)
+{
+  size_t bytes = safe_read (fd, buf, count);
+
+#if defined F_SETFL && O_NONBLOCK
+  if (bytes == SAFE_READ_ERROR && errno == EAGAIN)
+    {
+      int flags = fcntl (fd, F_GETFL);
+      if (0 <= flags && flags & O_NONBLOCK
+         && fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) != -1)
+       bytes = safe_read (fd, buf, count);
+    }
+#endif
+
+  return bytes;
+}
+
+/* Write to FD from the buffer BUF with COUNT bytes.  Do a full write.
+   Wait until an output buffer is available; this matters because
+   files are opened O_NONBLOCK for security reasons, and on some file
+   systems this can cause write to fail with errno == EAGAIN.  Return
+   the actual number of bytes written, setting errno if that is less
+   than COUNT.  */
+size_t
+blocking_write (int fd, void const *buf, size_t count)
+{
+  size_t bytes = full_write (fd, buf, count);
+
+#if defined F_SETFL && O_NONBLOCK
+  if (bytes < count && errno == EAGAIN)
+    {
+      int flags = fcntl (fd, F_GETFL);
+      if (0 <= flags && flags & O_NONBLOCK
+         && fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) != -1)
+       {
+         char const *buffer = buf;
+         bytes += full_write (fd, buffer + bytes, count - bytes);
+       }
+    }
+#endif
+
+  return bytes;
+}
+
 /* Set FD's (i.e., assuming the working directory is PARENTFD, FILE's)
    access time to ATIME.  */
 int
@@ -728,7 +778,6 @@ chdir_do (int i)
 {
   if (chdir_current != i)
     {
-      static size_t counter;
       struct wd *curr = &wd[i];
       int fd = curr->fd;
 
@@ -736,7 +785,8 @@ chdir_do (int i)
        {
          if (! IS_ABSOLUTE_FILE_NAME (curr->name))
            chdir_do (i - 1);
-         fd = openat (chdir_fd, curr->name, open_searchdir_flags);
+         fd = openat (chdir_fd, curr->name,
+                      open_searchdir_flags & ~ O_NOFOLLOW);
          if (fd < 0)
            open_fatal (curr->name);
 
@@ -856,21 +906,6 @@ file_removed_diag (const char *name, bool top_level,
     diagfn (name);
 }
 
-void
-dir_removed_diag (const char *name, bool top_level,
-                  void (*diagfn) (char const *name))
-{
-  if (!top_level && errno == ENOENT)
-    {
-      WARNOPT (WARN_FILE_REMOVED,
-              (0, 0, _("%s: Directory removed before we read it"),
-               quotearg_colon (name)));
-      set_exit_status (TAREXIT_DIFFERS);
-    }
-  else
-    diagfn (name);
-}
-
 void
 write_fatal_details (char const *name, ssize_t status, size_t size)
 {
@@ -927,7 +962,7 @@ page_aligned_alloc (void **ptr, size_t size)
 
 struct namebuf
 {
-  char *buffer;                /* directory, `/', and directory member */
+  char *buffer;                /* directory, '/', and directory member */
   size_t buffer_size;  /* allocated size of name_buffer */
   size_t dir_length;   /* length of directory part in buffer */
 };
This page took 0.024645 seconds and 4 git commands to generate.