diff options
author | 2015-09-04 16:33:37 -0500 | |
---|---|---|
committer | 2015-09-04 17:04:21 -0500 | |
commit | cd1de323f096fffd0ecfd8f87f6a8bdc4b2aba46 (patch) | |
tree | 42273422b1ae02c02d9a9c68a49c53a921465c34 | |
parent | f44ec114149146d616c262933f61583f572129ae (diff) | |
download | pseudo-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.txt | 4 | ||||
-rw-r--r-- | ports/unix/guts/mkdirat.c | 4 | ||||
-rw-r--r-- | ports/unix/guts/mkfifoat.c | 4 |
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. |