summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2016-01-22 15:15:36 -0600
committerPeter Seebach <peter.seebach@windriver.com>2016-01-22 15:15:57 -0600
commit735ac1b9ff7471b100f6758f9072bfd45e0e3f40 (patch)
tree1329b33c82cc5636dbb1c73672869cec5ee4ec0c
parent3bc3909fa70535c2ef876009dc58e577b10a7e0e (diff)
Fix mknod(...) with no file type bits
mknod(2) automatically defaults to S_IFREG if not given an explicit file type, so pseudo should too. Otherwise, GNU tar can (for some reason, it mostly does this when extracting xattrs?) invoke mknod instead of open with O_CREAT to create a file, and just provide the permission bits, and pseudo creates a "weird file" with no type bits in the database, which is unhelpful. Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
-rw-r--r--ChangeLog.txt3
-rw-r--r--ports/linux/guts/__xmknodat.c6
-rw-r--r--ports/unix/guts/mknodat.c6
-rw-r--r--pseudo.c5
4 files changed, 18 insertions, 2 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 5431f1e..cac7d63 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,6 @@
+2016-01-22:
+ * (seebs) Mask in S_IFREG when mknod called with no S_IFMT bits.
+
2015-09-22:
* (seebs) Fix modes after fopen/fopen64.
diff --git a/ports/linux/guts/__xmknodat.c b/ports/linux/guts/__xmknodat.c
index 296918a..4fa021b 100644
--- a/ports/linux/guts/__xmknodat.c
+++ b/ports/linux/guts/__xmknodat.c
@@ -11,6 +11,12 @@
/* mask out mode bits appropriately */
mode = mode & ~pseudo_umask;
+ /* if you don't specify a type, assume regular file */
+ if (!(mode & S_IFMT)) {
+ mode |= S_IFREG;
+ }
+ pseudo_debug(PDBGF_FILE, "xmknodat creating '%s', mode 0%o\n",
+ path ? path : "<no name>", (int) mode);
/* we don't use underlying call, so _ver is irrelevant to us */
(void) ver;
diff --git a/ports/unix/guts/mknodat.c b/ports/unix/guts/mknodat.c
index 76e4dd9..afeab46 100644
--- a/ports/unix/guts/mknodat.c
+++ b/ports/unix/guts/mknodat.c
@@ -12,6 +12,12 @@
/* mask out mode bits appropriately */
mode = mode & ~pseudo_umask;
+ /* if you don't specify a type, assume regular file */
+ if (!(mode & S_IFMT)) {
+ mode |= S_IFREG;
+ }
+ pseudo_debug(PDBGF_FILE, "mknodat creating '%s', mode 0%o\n",
+ path ? path : "<no name>", (int) mode);
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
if (dirfd != AT_FDCWD) {
diff --git a/pseudo.c b/pseudo.c
index 5715af2..e746c3f 100644
--- a/pseudo.c
+++ b/pseudo.c
@@ -1067,9 +1067,10 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon
msg->uid = (uid_t) -1;
msg->gid = (gid_t) -1;
#endif
- pseudo_debug(PDBGF_DB, "linking %s (uid -1 if xattr) for %s\n",
+ pseudo_debug(PDBGF_DB | PDBGF_XATTR, "linking %s (uid -1 if xattr) for %s, mode 0%o\n",
msg->pathlen ? msg->path : "no path",
- pseudo_op_name(msg->op));
+ pseudo_op_name(msg->op),
+ (int) msg->mode);
pdb_link_file(msg, &row);
}
if (pdb_set_xattr(row, oldpath, oldpathlen, xattr_flags)) {