aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2015-09-04 16:33:37 -0500
committerPeter Seebach <peter.seebach@windriver.com>2015-09-04 17:04:21 -0500
commitcd1de323f096fffd0ecfd8f87f6a8bdc4b2aba46 (patch)
tree42273422b1ae02c02d9a9c68a49c53a921465c34
parentf44ec114149146d616c262933f61583f572129ae (diff)
downloadpseudo-cd1de323f096fffd0ecfd8f87f6a8bdc4b2aba46.tar.gz
pseudo-cd1de323f096fffd0ecfd8f87f6a8bdc4b2aba46.tar.bz2
pseudo-cd1de323f096fffd0ecfd8f87f6a8bdc4b2aba46.zip
Don't have mkdirat set errno unintentionally
mkdirat() was calling real_fchmodat with invalid arguments (it turns out that AT_SYMLINK_NOFOLLOW is both irrelevant and forbidden by Linux), and the wrapper function did not restore errno to its previous value. This breaks localedef, because localedef is unconditionally storing the value of errno after a mkdir *whether or not the mkdir failed*, which is almost certainly wrong. Similar issue with mkfifoat. Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
-rw-r--r--ChangeLog.txt4
-rw-r--r--ports/unix/guts/mkdirat.c4
-rw-r--r--ports/unix/guts/mkfifoat.c4
3 files changed, 10 insertions, 2 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 9b39838..d12d5cc 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,5 +1,9 @@
2015-09-04:
* (seebs) add return value printing to wrapper debug!
+ * (seebs) make mkdirat() restore errno, also don't pass
+ AT_SYMLINK_NOFOLLOW to fchmodat() since it is ignored, and
+ we know that if the thing exists at all, it is a directory
+ and thus AT_SYMLINK_NOFOLLOW would be irrelevant anyway.
2015-09-03:
* (seebs) Use original mode, not 0600, for the chmods used to
diff --git a/ports/unix/guts/mkdirat.c b/ports/unix/guts/mkdirat.c
index 668d6ac..ef2e3a1 100644
--- a/ports/unix/guts/mkdirat.c
+++ b/ports/unix/guts/mkdirat.c
@@ -21,6 +21,7 @@
if (rc != -1) {
PSEUDO_STATBUF buf;
int stat_rc;
+ int save_errno = errno;
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
stat_rc = base_lstat(path, &buf);
@@ -33,12 +34,13 @@
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
real_fchmod(path, PSEUDO_FS_MODE(mode, 1));
#else
- real_fchmodat(dirfd, path, PSEUDO_FS_MODE(mode, 1), AT_SYMLINK_NOFOLLOW);
+ real_fchmodat(dirfd, path, PSEUDO_FS_MODE(mode, 1), 0);
#endif
} else {
pseudo_debug(PDBGF_OP, "mkdir of %s succeeded, but stat failed: %s\n",
path, strerror(errno));
}
+ errno = save_errno;
}
/* return rc;
diff --git a/ports/unix/guts/mkfifoat.c b/ports/unix/guts/mkfifoat.c
index 4546ba3..6947e70 100644
--- a/ports/unix/guts/mkfifoat.c
+++ b/ports/unix/guts/mkfifoat.c
@@ -33,6 +33,7 @@
if (rc == -1) {
return -1;
}
+ save_errno = errno;
rc = base_stat(path, &buf);
real_chmod(path, PSEUDO_FS_MODE(mode, 0));
#else
@@ -40,8 +41,9 @@
if (rc == -1) {
return -1;
}
+ save_errno = errno;
rc = base_fstatat(dirfd, path, &buf, AT_SYMLINK_NOFOLLOW);
- real_fchmodat(dirfd, path, PSEUDO_FS_MODE(mode, 0), AT_SYMLINK_NOFOLLOW);
+ real_fchmodat(dirfd, path, PSEUDO_FS_MODE(mode, 0), 0);
#endif
/* if the stat failed, we are going to give up and nuke
* any file we may have created, and hope for the best.