summaryrefslogtreecommitdiff
path: root/tar
diff options
context:
space:
mode:
Diffstat (limited to 'tar')
-rw-r--r--tar/bsdtar.127
-rw-r--r--tar/bsdtar.c6
-rw-r--r--tar/bsdtar.h2
-rw-r--r--tar/cmdline.c2
4 files changed, 37 insertions, 0 deletions
diff --git a/tar/bsdtar.1 b/tar/bsdtar.1
index 04b56553..723ea38f 100644
--- a/tar/bsdtar.1
+++ b/tar/bsdtar.1
@@ -469,6 +469,13 @@ This is the reverse of
and the default behavior if
.Nm
is run as non-root in x mode.
+.It Fl Fl no-safe-writes
+(x mode only)
+Do not create temporary files and use
+.Xr rename 2
+to replace the original ones.
+This is the reverse of
+.Fl Fl safe-writes .
.It Fl Fl no-same-owner
(x mode only)
Do not extract owner and group IDs.
@@ -756,6 +763,26 @@ The default is
.Ar hrs
which applies substitutions to all names.
In particular, it is never necessary to specify h, r, or s.
+.It Fl Fl safe-writes
+(x mode only)
+Extract files atomically.
+By default
+.Nm
+unlinks the original file with the same name as the extracted file (if it
+exists), and then creates it immediately under the same name and writes to
+it.
+For a short period of time, applications trying to access the file might
+not find it, or see incomplete results.
+If
+.Fl Fl safe-writes
+is enabled,
+.Nm
+first creates a unique temporary file, then writes the new contents to
+the temporary file, and finally renames the temporary file to its final
+name atomically using
+.Xr rename 2 .
+This guarantees that an application accessing the file, will either see
+the old contents or the new contents at all times.
.It Fl Fl same-owner
(x mode only)
Extract owner and group IDs.
diff --git a/tar/bsdtar.c b/tar/bsdtar.c
index b59963d0..af41be5e 100644
--- a/tar/bsdtar.c
+++ b/tar/bsdtar.c
@@ -542,6 +542,9 @@ main(int argc, char **argv)
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA;
bsdtar->flags |= OPTFLAG_NO_MAC_METADATA;
break;
+ case OPTION_NO_SAFE_WRITES:
+ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_SAFE_WRITES;
+ break;
case OPTION_NO_SAME_OWNER: /* GNU tar */
bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
break;
@@ -658,6 +661,9 @@ main(int argc, char **argv)
usage();
#endif
break;
+ case OPTION_SAFE_WRITES:
+ bsdtar->extract_flags |= ARCHIVE_EXTRACT_SAFE_WRITES;
+ break;
case OPTION_SAME_OWNER: /* GNU tar */
bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER;
break;
diff --git a/tar/bsdtar.h b/tar/bsdtar.h
index c9206dfd..89aa3aa9 100644
--- a/tar/bsdtar.h
+++ b/tar/bsdtar.h
@@ -164,6 +164,7 @@ enum {
OPTION_NO_ACLS,
OPTION_NO_FFLAGS,
OPTION_NO_MAC_METADATA,
+ OPTION_NO_SAFE_WRITES,
OPTION_NO_SAME_OWNER,
OPTION_NO_SAME_PERMISSIONS,
OPTION_NO_XATTRS,
@@ -177,6 +178,7 @@ enum {
OPTION_OPTIONS,
OPTION_PASSPHRASE,
OPTION_POSIX,
+ OPTION_SAFE_WRITES,
OPTION_SAME_OWNER,
OPTION_STRIP_COMPONENTS,
OPTION_TOTALS,
diff --git a/tar/cmdline.c b/tar/cmdline.c
index 21558e12..b80937ff 100644
--- a/tar/cmdline.c
+++ b/tar/cmdline.c
@@ -123,6 +123,7 @@ static const struct bsdtar_option {
{ "no-fflags", 0, OPTION_NO_FFLAGS },
{ "no-mac-metadata", 0, OPTION_NO_MAC_METADATA },
{ "no-recursion", 0, 'n' },
+ { "no-safe-writes", 0, OPTION_NO_SAFE_WRITES },
{ "no-same-owner", 0, OPTION_NO_SAME_OWNER },
{ "no-same-permissions", 0, OPTION_NO_SAME_PERMISSIONS },
{ "no-xattr", 0, OPTION_NO_XATTRS },
@@ -144,6 +145,7 @@ static const struct bsdtar_option {
{ "posix", 0, OPTION_POSIX },
{ "preserve-permissions", 0, 'p' },
{ "read-full-blocks", 0, 'B' },
+ { "safe-writes", 0, OPTION_SAFE_WRITES },
{ "same-owner", 0, OPTION_SAME_OWNER },
{ "same-permissions", 0, 'p' },
{ "strip-components", 1, OPTION_STRIP_COMPONENTS },