summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2015-11-23 10:09:06 +0100
committerGedare Bloom <gedare@rtems.org>2015-11-23 10:40:06 -0500
commita6d176f25e28c153b304ee6c8ca6690b04722448 (patch)
tree13024f4ad310045b9fa720f713fbb454d60b864b /cpukit
parentbsp/tms570: unite code duplication in pinmux and clean SCI close per review r... (diff)
downloadrtems-a6d176f25e28c153b304ee6c8ca6690b04722448.tar.bz2
untar: do not exit with error when created directory already exists.
The problem exists for both RTEMS untar implementations and their variants: Untar_FromMemory(), Untar_FromFile() and rtems_tarfs_load(). If filesystem object already exists at extracted directory path then if it is directory, creation is ignored. Attempt to delete/unlink object and make directory is tried for other cases. This simple approach problem reported in ticket fixes #2413. Behavior follows GNU tar and BSD tar practice for directories but much more work is required to achieve full semantics of the full featured tar implementation still.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/libfs/src/imfs/imfs_load_tar.c18
-rw-r--r--cpukit/libmisc/untar/untar.c30
2 files changed, 46 insertions, 2 deletions
diff --git a/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c
index 7228978094..adc91dd054 100644
--- a/cpukit/libfs/src/imfs/imfs_load_tar.c
+++ b/cpukit/libfs/src/imfs/imfs_load_tar.c
@@ -103,8 +103,24 @@ int rtems_tarfs_load(
strcat(full_filename, "/");
++len;
strncat(full_filename, filename, 256-len-1);
- rv = mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);
+ if ( mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO) != 0 ) {
+ if (errno == EEXIST) {
+ struct stat stat_buf;
+ if ( stat(full_filename, &stat_buf) == 0 ) {
+ if ( S_ISDIR(stat_buf.st_mode) ) {
+ continue;
+ } else {
+ if ( unlink(full_filename) != -1 ) {
+ if ( mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO) == 0 )
+ continue;
+ }
+ }
+ }
+ }
+ rv = -1;
+ }
}
+
/*
* Create a LINEAR_FILE node
*/
diff --git a/cpukit/libmisc/untar/untar.c b/cpukit/libmisc/untar/untar.c
index aed8fed356..e4b0aeb968 100644
--- a/cpukit/libmisc/untar/untar.c
+++ b/cpukit/libmisc/untar/untar.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <rtems/untar.h>
@@ -203,6 +204,19 @@ Untar_FromMemory(
}
} else if (linkflag == DIRTYPE) {
if ( mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) != 0 ) {
+ if (errno == EEXIST) {
+ struct stat stat_buf;
+ if ( stat(fname, &stat_buf) == 0 ) {
+ if ( S_ISDIR(stat_buf.st_mode) ) {
+ continue;
+ } else {
+ if ( unlink(fname) != -1 ) {
+ if ( mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0 )
+ continue;
+ }
+ }
+ }
+ }
printk("Untar: failed to create directory %s\n", fname);
retval = UNTAR_FAIL;
break;
@@ -319,7 +333,21 @@ Untar_FromFile(
close(out_fd);
}
} else if (linkflag == DIRTYPE) {
- (void) mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
+ if ( mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) != 0 ) {
+ if (errno == EEXIST) {
+ struct stat stat_buf;
+ if ( stat(fname, &stat_buf) == 0 ) {
+ if ( S_ISDIR(stat_buf.st_mode) ) {
+ continue;
+ } else {
+ if ( unlink(fname) != -1 ) {
+ if ( mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0 )
+ continue;
+ }
+ }
+ }
+ }
+ }
}
}
free(bufr);