summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ctx.c3
-rw-r--r--src/ctx.h4
-rw-r--r--src/parse.c23
-rw-r--r--tests/bfs/perm_leading_plus_symbolic.out5
-rw-r--r--tests/posix/perm_leading_plus_symbolic_minus.out5
-rw-r--r--tests/posix/perm_leading_plus_umask.out10
-rw-r--r--tests/posix/perm_leading_plus_umask.sh3
7 files changed, 43 insertions, 10 deletions
diff --git a/src/ctx.c b/src/ctx.c
index 0f619c2..8fafb32 100644
--- a/src/ctx.c
+++ b/src/ctx.c
@@ -52,6 +52,9 @@ struct bfs_ctx *bfs_ctx_new(void) {
trie_init(&ctx->files);
+ ctx->umask = umask(0);
+ umask(ctx->umask);
+
if (getrlimit(RLIMIT_NOFILE, &ctx->orig_nofile) != 0) {
goto fail;
}
diff --git a/src/ctx.h b/src/ctx.h
index b28a63c..064e8b0 100644
--- a/src/ctx.h
+++ b/src/ctx.h
@@ -16,6 +16,7 @@
#include "trie.h"
#include <stddef.h>
#include <sys/resource.h>
+#include <sys/types.h>
#include <time.h>
struct CFILE;
@@ -98,6 +99,9 @@ struct bfs_ctx {
/** The number of files owned by the context. */
int nfiles;
+ /** The current file creation mask. */
+ mode_t umask;
+
/** The initial RLIMIT_NOFILE limits. */
struct rlimit orig_nofile;
/** The current RLIMIT_NOFILE limits. */
diff --git a/src/parse.c b/src/parse.c
index c6030e7..6a1b34c 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -1901,6 +1901,8 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
return 0;
}
+ mode_t umask = parser->ctx->umask;
+
expr->file_mode = 0;
expr->dir_mode = 0;
@@ -1938,6 +1940,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
} op uninit(MODE_EQUALS);
mode_t who uninit(0);
+ mode_t mask uninit(0);
mode_t file_change uninit(0);
mode_t dir_change uninit(0);
@@ -1946,6 +1949,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
switch (state) {
case MODE_CLAUSE:
who = 0;
+ mask = 0777;
state = MODE_WHO;
fallthru;
@@ -1989,6 +1993,9 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
case MODE_ACTION:
if (who == 0) {
who = 0777;
+ mask = who & ~umask;
+ } else {
+ mask = who;
}
switch (*i) {
@@ -2048,27 +2055,27 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
}
file_change |= (file_change << 6) | (file_change << 3);
- file_change &= who;
+ file_change &= mask;
dir_change |= (dir_change << 6) | (dir_change << 3);
- dir_change &= who;
+ dir_change &= mask;
state = MODE_ACTION_APPLY;
break;
case MODE_PERM:
switch (*i) {
case 'r':
- file_change |= who & 0444;
- dir_change |= who & 0444;
+ file_change |= mask & 0444;
+ dir_change |= mask & 0444;
break;
case 'w':
- file_change |= who & 0222;
- dir_change |= who & 0222;
+ file_change |= mask & 0222;
+ dir_change |= mask & 0222;
break;
case 'x':
- file_change |= who & 0111;
+ file_change |= mask & 0111;
fallthru;
case 'X':
- dir_change |= who & 0111;
+ dir_change |= mask & 0111;
break;
case 's':
if (who & 0700) {
diff --git a/tests/bfs/perm_leading_plus_symbolic.out b/tests/bfs/perm_leading_plus_symbolic.out
index fdc175d..09bc88f 100644
--- a/tests/bfs/perm_leading_plus_symbolic.out
+++ b/tests/bfs/perm_leading_plus_symbolic.out
@@ -1,2 +1,3 @@
-perms/drwxrwxrwx
-perms/frwxrwxrwx
+perms
+perms/drwxr-xr-x
+perms/frwxr-xr-x
diff --git a/tests/posix/perm_leading_plus_symbolic_minus.out b/tests/posix/perm_leading_plus_symbolic_minus.out
index fdc175d..38d0e1c 100644
--- a/tests/posix/perm_leading_plus_symbolic_minus.out
+++ b/tests/posix/perm_leading_plus_symbolic_minus.out
@@ -1,2 +1,7 @@
+perms
+perms/drwxr-xr-x
+perms/drwxrwxr-x
perms/drwxrwxrwx
+perms/frwxr-xr-x
+perms/frwxrwxr-x
perms/frwxrwxrwx
diff --git a/tests/posix/perm_leading_plus_umask.out b/tests/posix/perm_leading_plus_umask.out
new file mode 100644
index 0000000..6ed4b7f
--- /dev/null
+++ b/tests/posix/perm_leading_plus_umask.out
@@ -0,0 +1,10 @@
+perms/drwxrwxr-x
+perms/drwxrwxrwx
+perms/f-w--w----
+perms/f-w--w--w-
+perms/f-wx-wx--x
+perms/f-wx-wx-wx
+perms/frw-rw-r--
+perms/frw-rw-rw-
+perms/frwxrwxr-x
+perms/frwxrwxrwx
diff --git a/tests/posix/perm_leading_plus_umask.sh b/tests/posix/perm_leading_plus_umask.sh
new file mode 100644
index 0000000..948b4ad
--- /dev/null
+++ b/tests/posix/perm_leading_plus_umask.sh
@@ -0,0 +1,3 @@
+# Test for https://www.austingroupbugs.net/view.php?id=1392
+umask 002
+bfs_diff perms -perm -+w