summaryrefslogtreecommitdiff
path: root/utils.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2018-03-14 15:22:12 +0100
committerAtomic Bot <atomic-devel@projectatomic.io>2018-03-16 22:07:13 +0000
commit1e90a18a085e324b821a8bd0dc28a27082e43634 (patch)
tree563dbd09053d11ca8689dba24bfa61266f32fc3c /utils.c
parent3c488585bd9897c842c1708ddb413adee5a9b43a (diff)
downloadbubblewrap-1e90a18a085e324b821a8bd0dc28a27082e43634.tar.gz
Don't rely on mkdir returning EEXISTS (fixing NFS)
For NFS mounts if we call mkdir() on a read-only mount (such as when we've created a read-only bind mount) the kernel will nor return EEXIST even when the directory exists, instead returning EROFS. So, we add (and use) an ensure_dir() helper that stats before calling mkdir. Closes: #258 Approved by: giuseppe
Diffstat (limited to 'utils.c')
-rw-r--r--utils.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/utils.c b/utils.c
index a74fa36..f43bc5e 100644
--- a/utils.c
+++ b/utils.c
@@ -434,7 +434,7 @@ ensure_file (const char *path,
/* We check this ahead of time, otherwise
the create file will fail in the read-only
- case with EROFD instead of EEXIST */
+ case with EROFS instead of EEXIST */
if (stat (path, &buf) == 0 &&
S_ISREG (buf.st_mode))
return 0;
@@ -593,6 +593,34 @@ get_file_mode (const char *pathname)
return buf.st_mode & S_IFMT;
}
+int
+ensure_dir (const char *path,
+ mode_t mode)
+{
+ struct stat buf;
+
+ /* We check this ahead of time, otherwise
+ the mkdir call can fail in the read-only
+ case with EROFS instead of EEXIST on some
+ filesystems (such as NFS) */
+ if (stat (path, &buf) == 0)
+ {
+ if (!S_ISDIR (buf.st_mode))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+
+ return 0;
+ }
+
+ if (mkdir (path, mode) == -1 && errno != EEXIST)
+ return -1;
+
+ return 0;
+}
+
+
/* Sets errno on error (!= 0) */
int
mkdir_with_parents (const char *pathname,
@@ -601,7 +629,6 @@ mkdir_with_parents (const char *pathname,
{
cleanup_free char *fn = NULL;
char *p;
- struct stat buf;
if (pathname == NULL || *pathname == '\0')
{
@@ -628,16 +655,8 @@ mkdir_with_parents (const char *pathname,
if (!create_last && p == NULL)
break;
- if (stat (fn, &buf) != 0)
- {
- if (mkdir (fn, mode) == -1 && errno != EEXIST)
- return -1;
- }
- else if (!S_ISDIR (buf.st_mode))
- {
- errno = ENOTDIR;
- return -1;
- }
+ if (ensure_dir (fn, mode) != 0)
+ return -1;
if (p)
{