]> granicus.if.org Git - strace/commitdiff
Fix printing of mode_t, umode_t, and umask types
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 3 Aug 2016 14:05:39 +0000 (14:05 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 3 Aug 2016 23:27:03 +0000 (23:27 +0000)
Print numeric umode_t type using %#03ho format.
Print return value of umask syscall using %#03lo format.
When printing symbolic mode_t type, always print lower 9 bits,
and print the numeric part using %#03o format.

* defs.h (sprintmode): Remove.
(print_symbolic_mode_t, print_numeric_umode_t,
print_numeric_long_umask): New prototypes.
* printmode.c (sprintmode): Remove.
(print_symbolic_mode_t, print_numeric_umode_t,
print_numeric_long_umask): New functions.
* chmod.c (decode_chmod): Use print_numeric_umode_t.
* ipc_msg.c (SYS_FUNC(msgget)): Likewise.
* ipc_msgctl.c (print_msqid_ds): Likewise.
* ipc_sem.c (SYS_FUNC(semget)): Likewise.
* ipc_shm.c (SYS_FUNC(shmget)): Likewise.
* ipc_shmctl.c (print_shmid_ds): Likewise.
* mq.c (SYS_FUNC(mq_open)): Likewise.
* open.c (decode_open, SYS_FUNC(creat)): Likewise.
* umask.c (SYS_FUNC(umask)): Likewise.
* mknod.c (decode_mknod): Use print_symbolic_mode_t.
* printstat.h (DO_PRINTSTAT): Likewise.
* syscall.c (trace_syscall_exiting): Use print_numeric_long_umask.
* tests/umode_t.c: New file.
* tests/Makefile.am (EXTRA_DIST): Add it.
* tests/creat.c: Rewrite as a thin wrapper around umode_t.c
* tests/mkdir.c: Likewise.
* tests/mkdirat.c: Likewise.
* tests/mknod.c: Extend test coverage of mknod syscall.
* tests/mknodat.c: Extend test coverage of mknodat syscall.
* tests/umask.c: Extend test coverage of umask syscall.
* tests/creat.test: Update the value specified for strace -a parameter.
* tests/mkdir.test: Likewise.
* tests/mkdirat.test: Likewise.
* tests/mknodat.test: Likewise.

26 files changed:
chmod.c
defs.h
ipc_msg.c
ipc_msgctl.c
ipc_sem.c
ipc_shm.c
ipc_shmctl.c
mknod.c
mq.c
open.c
printmode.c
printstat.h
syscall.c
tests/Makefile.am
tests/creat.c
tests/creat.test
tests/mkdir.c
tests/mkdir.test
tests/mkdirat.c
tests/mkdirat.test
tests/mknod.c
tests/mknodat.c
tests/mknodat.test
tests/umask.c
tests/umode_t.c [new file with mode: 0644]
umask.c

diff --git a/chmod.c b/chmod.c
index 83741c9e2abe9336a449b6d8c6027d8fba5a7e28..fd76490c08031f87ba340839b2fa7bcb8140cf23 100644 (file)
--- a/chmod.c
+++ b/chmod.c
@@ -4,7 +4,8 @@ static void
 decode_chmod(struct tcb *tcp, const int offset)
 {
        printpath(tcp, tcp->u_arg[offset]);
-       tprintf(", %#lo", tcp->u_arg[offset + 1]);
+       tprints(", ");
+       print_numeric_umode_t(tcp->u_arg[offset + 1]);
 }
 
 SYS_FUNC(chmod)
@@ -25,7 +26,8 @@ SYS_FUNC(fchmodat)
 SYS_FUNC(fchmod)
 {
        printfd(tcp, tcp->u_arg[0]);
-       tprintf(", %#lo", tcp->u_arg[1]);
+       tprints(", ");
+       print_numeric_umode_t(tcp->u_arg[1]);
 
        return RVAL_DECODED;
 }
diff --git a/defs.h b/defs.h
index 4b7e8eddbe13a59cff39aaf93400c89e77787474..bfe76e2d3b739bcf091724c724c847ef918ebcd7 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -624,8 +624,10 @@ extern int printargs_d(struct tcb *);
 extern void addflags(const struct xlat *, uint64_t);
 extern int printflags64(const struct xlat *, uint64_t, const char *);
 extern const char *sprintflags(const char *, const struct xlat *, uint64_t);
-extern const char *sprintmode(unsigned int);
 extern const char *sprinttime(time_t);
+extern void print_symbolic_mode_t(unsigned int);
+extern void print_numeric_umode_t(unsigned short);
+extern void print_numeric_long_umask(unsigned long);
 extern void dumpiov_in_msghdr(struct tcb *, long, unsigned long);
 extern void dumpiov_in_mmsghdr(struct tcb *, long);
 extern void dumpiov_upto(struct tcb *, int, long, unsigned long);
index daa0036529b125d746444b08f8c804fbbd459724..f04d14d76a26fe224b8a3ed1f33afe13a3ca3ecd 100644 (file)
--- a/ipc_msg.c
+++ b/ipc_msg.c
@@ -50,7 +50,7 @@ SYS_FUNC(msgget)
                tprints("IPC_PRIVATE, ");
        if (printflags(resource_flags, tcp->u_arg[1] & ~0777, NULL) != 0)
                tprints("|");
-       tprintf("%#lo", tcp->u_arg[1] & 0777);
+       print_numeric_umode_t(tcp->u_arg[1] & 0777);
        return RVAL_DECODED;
 }
 
index e46f6e2e5a723fa57dced8a433ccb52b3d6de2a0..9be35cefabadcc0ca5b422153aa53e7212d9eb35 100644 (file)
@@ -67,7 +67,7 @@ print_msqid_ds(struct tcb *tcp, const long addr, int cmd)
                printuid("uid=", msqid_ds.msg_perm.uid);
                printuid(", gid=", msqid_ds.msg_perm.gid);
                tprints(", mode=");
-               tprints(sprintmode(msqid_ds.msg_perm.mode));
+               print_numeric_umode_t(msqid_ds.msg_perm.mode);
 
                if (cmd != IPC_STAT) {
                        tprints("}, ...}");
index ba21b7bb9f1c93499f82929fe0e5ca2d21f9ab51..bf82f330c882aabed6aadb510a8b9d0c5be8d936 100644 (file)
--- a/ipc_sem.c
+++ b/ipc_sem.c
@@ -108,7 +108,7 @@ SYS_FUNC(semget)
        tprintf(", %lu, ", tcp->u_arg[1]);
        if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0)
                tprints("|");
-       tprintf("%#lo", tcp->u_arg[2] & 0777);
+       print_numeric_umode_t(tcp->u_arg[2] & 0777);
        return RVAL_DECODED;
 }
 
index c418884a5b9223acc1c63f2d562a84b522a1c83f..b2059c2b3a4fcf11007fb26da78eee7e8d20d4e2 100644 (file)
--- a/ipc_shm.c
+++ b/ipc_shm.c
@@ -50,7 +50,7 @@ SYS_FUNC(shmget)
        tprintf(", %lu, ", tcp->u_arg[1]);
        if (printflags(shm_resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0)
                tprints("|");
-       tprintf("%#lo", tcp->u_arg[2] & 0777);
+       print_numeric_umode_t(tcp->u_arg[2] & 0777);
        return RVAL_DECODED;
 }
 
index 3498455de370992e82d6f54b6ab092587d969f45..7ea3672927a1f39ad2c253c7c6f0a4735b1cfeb0 100644 (file)
@@ -67,7 +67,7 @@ print_shmid_ds(struct tcb *tcp, const long addr, int cmd)
                printuid("uid=", shmid_ds.shm_perm.uid);
                printuid(", gid=", shmid_ds.shm_perm.gid);
                tprints(", mode=");
-               tprints(sprintmode(shmid_ds.shm_perm.mode));
+               print_numeric_umode_t(shmid_ds.shm_perm.mode);
 
                if (cmd != IPC_STAT) {
                        tprints("}, ...}");
diff --git a/mknod.c b/mknod.c
index d78fa07febf2bd481532f7a0251302991a3a2b84..dbcffd7f0b84bbe61e0f3c6c873b01d41f11a887 100644 (file)
--- a/mknod.c
+++ b/mknod.c
 static void
 decode_mknod(struct tcb *tcp, int offset)
 {
-       int mode = tcp->u_arg[offset + 1];
+       unsigned short mode = tcp->u_arg[offset + 1];
        unsigned int dev;
 
        printpath(tcp, tcp->u_arg[offset]);
-       tprintf(", %s", sprintmode(mode));
+       tprints(", ");
+       print_symbolic_mode_t(mode);
        switch (mode & S_IFMT) {
        case S_IFCHR:
        case S_IFBLK:
diff --git a/mq.c b/mq.c
index e12eef7c6ab3e25d672d508364a39e5e529a2131..1df2aa1f9c2f6e2b36d323fbd51d7b03aace9826 100644 (file)
--- a/mq.c
+++ b/mq.c
@@ -37,7 +37,9 @@ SYS_FUNC(mq_open)
        tprint_open_modes(tcp->u_arg[1]);
        if (tcp->u_arg[1] & O_CREAT) {
                /* mode */
-               tprintf(", %#lo, ", tcp->u_arg[2]);
+               tprints(", ");
+               print_numeric_umode_t(tcp->u_arg[2]);
+               tprints(", ");
                printmqattr(tcp, tcp->u_arg[3]);
        }
        return RVAL_DECODED;
diff --git a/open.c b/open.c
index 90dd10fe2d8f08ebb81c8f7a404c62e289b319fc..b712a229c7735d37387cc2356405cf6f7971c7b7 100644 (file)
--- a/open.c
+++ b/open.c
@@ -124,7 +124,8 @@ decode_open(struct tcb *tcp, int offset)
        tprint_open_modes(tcp->u_arg[offset + 1]);
        if (tcp->u_arg[offset + 1] & O_CREAT) {
                /* mode */
-               tprintf(", %#lo", tcp->u_arg[offset + 2]);
+               tprints(", ");
+               print_numeric_umode_t(tcp->u_arg[offset + 2]);
        }
 
        return RVAL_DECODED | RVAL_FD;
@@ -144,7 +145,8 @@ SYS_FUNC(openat)
 SYS_FUNC(creat)
 {
        printpath(tcp, tcp->u_arg[0]);
-       tprintf(", %#lo", tcp->u_arg[1]);
+       tprints(", ");
+       print_numeric_umode_t(tcp->u_arg[1]);
 
        return RVAL_DECODED | RVAL_FD;
 }
index ad8750782a62aaf6dac699a8ca8d7e67a9274289..1babed6dac9a0a0f1da429ac6a9c7caafa53016a 100644 (file)
 
 #include "xlat/modetypes.h"
 
-const char *
-sprintmode(unsigned int mode)
+void
+print_symbolic_mode_t(const unsigned int mode)
 {
-       static char buf[sizeof("S_IFSOCK|S_ISUID|S_ISGID|S_ISVTX|%o")
-                       + sizeof(int)*3
-                       + /*paranoia:*/ 8];
-       const char *s;
-
-       if ((mode & S_IFMT) == 0)
-               s = "";
-       else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
-               sprintf(buf, "%#o", mode);
-               return buf;
+       const char *ifmt;
+
+       if (mode & S_IFMT) {
+               ifmt = xlookup(modetypes, mode & S_IFMT);
+               if (!ifmt) {
+                       tprintf("%#03o", mode);
+                       return;
+               }
+       } else {
+               ifmt = NULL;
        }
-       s = buf + sprintf(buf, "%s%s%s%s", s,
-               (mode & S_ISUID) ? "|S_ISUID" : "",
-               (mode & S_ISGID) ? "|S_ISGID" : "",
-               (mode & S_ISVTX) ? "|S_ISVTX" : "");
-       mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
-       if (mode)
-               sprintf((char*)s, "|%#o", mode);
-       s = (*buf == '|') ? buf + 1 : buf;
-       return *s ? s : "0";
+
+       tprintf("%s%s%s%s%s%#03o",
+               ifmt ? ifmt : "",
+               ifmt ? "|" : "",
+               (mode & S_ISUID) ? "S_ISUID|" : "",
+               (mode & S_ISGID) ? "S_ISGID|" : "",
+               (mode & S_ISVTX) ? "S_ISVTX|" : "",
+               mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX));
+}
+
+void
+print_numeric_umode_t(const unsigned short mode)
+{
+       tprintf("%#03ho", mode);
+}
+
+void
+print_numeric_long_umask(const unsigned long mode)
+{
+       tprintf("%#03lo", mode);
 }
index 5bf745c5f6478d47ce01eee16d359f9143c7ae1e..562d5cadf50eaf2371c1208d19a865a74bf663bd 100644 (file)
 static void
 DO_PRINTSTAT(struct tcb *tcp, const STRUCT_STAT *statbuf)
 {
+       tprints("{");
        if (!abbrev(tcp)) {
-               tprintf("{st_dev=makedev(%u, %u), st_ino=%llu, st_mode=%s, ",
+               tprintf("st_dev=makedev(%u, %u), st_ino=%llu, st_mode=",
                        (unsigned int) STAT_MAJOR(statbuf->st_dev),
                        (unsigned int) STAT_MINOR(statbuf->st_dev),
-                       widen_to_ull(statbuf->st_ino),
-                       sprintmode(statbuf->st_mode));
-               tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
+                       widen_to_ull(statbuf->st_ino));
+               print_symbolic_mode_t(statbuf->st_mode);
+               tprintf(", st_nlink=%u, st_uid=%u, st_gid=%u",
                        (unsigned int) statbuf->st_nlink,
                        (unsigned int) statbuf->st_uid,
                        (unsigned int) statbuf->st_gid);
 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
-               tprintf("st_blksize=%u, ", (unsigned int) statbuf->st_blksize);
+               tprintf(", st_blksize=%u", (unsigned int) statbuf->st_blksize);
 #endif
 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
-               tprintf("st_blocks=%llu, ", widen_to_ull(statbuf->st_blocks));
+               tprintf(", st_blocks=%llu", widen_to_ull(statbuf->st_blocks));
 #endif
        } else {
-               tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
+               tprints("st_mode=");
+               print_symbolic_mode_t(statbuf->st_mode);
        }
 
        switch (statbuf->st_mode & S_IFMT) {
        case S_IFCHR: case S_IFBLK:
 #ifdef HAVE_STRUCT_STAT_ST_RDEV
-               tprintf("st_rdev=makedev(%u, %u), ",
+               tprintf(", st_rdev=makedev(%u, %u)",
                        (unsigned int) STAT_MAJOR(statbuf->st_rdev),
                        (unsigned int) STAT_MINOR(statbuf->st_rdev));
 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
-               tprintf("st_size=makedev(%u, %u), ",
+               tprintf(", st_size=makedev(%u, %u)",
                        (unsigned int) STAT_MAJOR(statbuf->st_size),
                        (unsigned int) STAT_MINOR(statbuf->st_size));
 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
                break;
        default:
-               tprintf("st_size=%llu, ", widen_to_ull(statbuf->st_size));
+               tprintf(", st_size=%llu", widen_to_ull(statbuf->st_size));
                break;
        }
 
        if (!abbrev(tcp)) {
                const bool cast = sizeof(statbuf->st_atime) == sizeof(int);
 
-               tprints("st_atime=");
+               tprints("st_atime=");
                tprints(sprinttime(cast ? (time_t) (int) statbuf->st_atime:
                                          (time_t) statbuf->st_atime));
 #ifdef HAVE_STRUCT_STAT_ST_ATIME_NSEC
@@ -122,10 +124,10 @@ DO_PRINTSTAT(struct tcb *tcp, const STRUCT_STAT *statbuf)
 #ifdef HAVE_STRUCT_STAT_ST_GEN
                tprintf(", st_gen=%u", (unsigned int) statbuf->st_gen);
 #endif
-               tprints("}");
        } else {
-               tprints("...}");
+               tprints(", ...");
        }
+       tprints("}");
 }
 
 #undef STAT_MINOR
index 6af0dec028dc706162d119aec9f0fb6c9b30a382..e5ac7db55e5f36b7634a0c66a25abd9a4abf7da9 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -1040,7 +1040,8 @@ trace_syscall_exiting(struct tcb *tcp)
                                        tprintf("= %#lx", tcp->u_rval);
                                break;
                        case RVAL_OCTAL:
-                               tprintf("= %#lo", tcp->u_rval);
+                               tprints("= ");
+                               print_numeric_long_umask(tcp->u_rval);
                                break;
                        case RVAL_UDECIMAL:
 #if SUPPORTED_PERSONALITIES > 1
index 69b690653d97d56ebdda07ea583da19c4902e250..3fa3b3b0e645fbf66aed3c3fa787c5fcf30c9460 100644 (file)
@@ -759,6 +759,7 @@ EXTRA_DIST = init.sh run.sh match.awk \
             struct_flock.c \
             sun_path.expected \
             uio.expected \
+            umode_t.c \
             umovestr.expected \
             unix-pair-send-recv.expected \
             unix-pair-sendto-recvfrom.expected \
index 8572e7f4f22a2200bf4d306dcf757e211ec4e8c0..89fcef9b01637bbb9f878d82a31df3ce53af1b19 100644 (file)
@@ -3,21 +3,9 @@
 
 #ifdef __NR_creat
 
-# include <stdio.h>
-# include <unistd.h>
-
-# define TMP_FILE "creat"
-
-int
-main(void)
-{
-       long rc = syscall(__NR_creat, TMP_FILE, 0400);
-       printf("creat(\"%s\", %#o) = %ld %s (%m)\n",
-              TMP_FILE, 0400, rc, errno2name());
-
-       puts("+++ exited with 0 +++");
-       return 0;
-}
+# define TEST_SYSCALL_NR __NR_creat
+# define TEST_SYSCALL_STR "creat"
+# include "umode_t.c"
 
 #else
 
index 49fddd215a29f2c123e86d5d6b57be5ae7debd9c..069648f7e46a83275ab4e8929bbe41a600750e51 100755 (executable)
@@ -3,4 +3,4 @@
 # Check creat syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff -a21
+run_strace_match_diff -a20
index dbb43c3bf247c62ef4d43201c5abbf1c582eb523..79fe94f121524d7aa8748bb3080a888d4c7eaf81 100644 (file)
@@ -3,21 +3,9 @@
 
 #ifdef __NR_mkdir
 
-# include <stdio.h>
-# include <unistd.h>
-
-int
-main(void)
-{
-       static const char sample[] = "mkdir";
-
-       long rc = syscall(__NR_mkdir, sample, 0600);
-       printf("mkdir(\"%s\", 0600) = %ld %s (%m)\n",
-              sample, rc, errno2name());
-
-       puts("+++ exited with 0 +++");
-       return 0;
-}
+# define TEST_SYSCALL_NR __NR_mkdir
+# define TEST_SYSCALL_STR "mkdir"
+# include "umode_t.c"
 
 #else
 
index 98d5a526b780b21c59fbdaaf8636909f3cc41b4d..38ed6928ac57c342bfa4a3d69ac9eb69e63d31e5 100755 (executable)
@@ -3,4 +3,4 @@
 # Check mkdir syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff -a21
+run_strace_match_diff -a20
index cbdf16c5ed37f6b0ecf59063e628bdf19085ad85..fc2732d0e8482f57b7e0503975103f944eb8630e 100644 (file)
@@ -3,22 +3,11 @@
 
 #ifdef __NR_mkdirat
 
-# include <stdio.h>
-# include <unistd.h>
-
-int
-main(void)
-{
-       static const char sample[] = "mkdirat.sample";
-       const long fd = (long) 0xdeadbeefffffffff;
-
-       long rc = syscall(__NR_mkdirat, fd, sample, 0600);
-       printf("mkdirat(%d, \"%s\", 0600) = %ld %s (%m)\n",
-              (int) fd, sample, rc, errno2name());
-
-       puts("+++ exited with 0 +++");
-       return 0;
-}
+# define TEST_SYSCALL_NR               __NR_mkdirat
+# define TEST_SYSCALL_STR              "mkdirat"
+# define TEST_SYSCALL_PREFIX_ARGS      (long int) 0xdeadbeefffffffff,
+# define TEST_SYSCALL_PREFIX_STR       "-1, "
+# include "umode_t.c"
 
 #else
 
index e41ce3575dd0c5112998ca6023ede6914ecd176a..0fcb841a9f9712f32f5059cd693b7ca0684b1483 100755 (executable)
@@ -3,4 +3,4 @@
 # Check mkdirat syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff -a36
+run_strace_match_diff -a28
index 91ce751e2b3f7ff035c9f400af7e89b83732cb33..4847f32ab20051bc855dcf1d80d35fb991db1494 100644 (file)
 #  include <sys/mkdev.h>
 # endif
 
-# define TMP_FILE "mknod"
+static const char sample[] = "mknod";
+
+static long
+call_mknod(unsigned short mode, unsigned long dev)
+{
+       unsigned long lmode = (unsigned long) 0xffffffffffff0000 | mode;
+       return syscall(__NR_mknod, sample, lmode, dev);
+}
 
 int
 main(void)
 {
-       long rc = syscall(__NR_mknod, TMP_FILE, 0, 0xdeadbeef);
-       printf("mknod(\"%s\", 0) = %ld %s (%m)\n",
-              TMP_FILE, rc, errno2name());
+       unsigned long dev = (unsigned long) 0xdeadbeefbadc0ded;
+
+       long rc = call_mknod(0, dev);
+       printf("mknod(\"%s\", 000) = %ld %s (%m)\n",
+              sample, rc, errno2name());
+
+       rc = call_mknod(0xffff, dev);
+       printf("mknod(\"%s\", %#03ho) = %ld %s (%m)\n",
+              sample, (unsigned short) -1, rc, errno2name());
+
+       rc = call_mknod(S_IFREG, 0);
+       printf("mknod(\"%s\", S_IFREG|000) = %ld %s (%m)\n",
+              sample, rc, errno2name());
+
+       rc = call_mknod(S_IFDIR | 06, 0);
+       printf("mknod(\"%s\", S_IFDIR|006) = %ld %s (%m)\n",
+              sample, rc, errno2name());
 
-       rc = syscall(__NR_mknod, TMP_FILE, -1L, 0xdeadbeef);
-       printf("mknod(\"%s\", %#o) = %ld %s (%m)\n",
-              TMP_FILE, -1, rc, errno2name());
+       rc = call_mknod(S_IFLNK | 060, 0);
+       printf("mknod(\"%s\", S_IFLNK|060) = %ld %s (%m)\n",
+              sample, rc, errno2name());
 
-       rc = syscall(__NR_mknod, TMP_FILE, S_IFREG|0600, 0);
-       printf("mknod(\"%s\", S_IFREG|0600) = %ld %s (%m)\n",
-              TMP_FILE, rc, errno2name());
+       rc = call_mknod(S_IFIFO | 0600, 0);
+       printf("mknod(\"%s\", S_IFIFO|0600) = %ld %s (%m)\n",
+              sample, rc, errno2name());
 
-       unsigned long dev =
-               (unsigned long) 0xdeadbeef00000000 | makedev(1, 7);
+       dev = (unsigned long) 0xdeadbeef00000000 | makedev(1, 7);
 
-       rc = syscall(__NR_mknod, TMP_FILE, S_IFCHR | 0400, dev);
-       printf("mknod(\"%s\", S_IFCHR|0400, makedev(1, 7)) = %ld %s (%m)\n",
-              TMP_FILE, rc, errno2name());
+       rc = call_mknod(S_IFCHR | 024, dev);
+       printf("mknod(\"%s\", S_IFCHR|024, makedev(1, 7)) = %ld %s (%m)\n",
+              sample, rc, errno2name());
 
-       const unsigned long mode =
-               ((unsigned long) 0xfacefeedffffffff & ~S_IFMT) | S_IFBLK;
+       const unsigned short mode = (0xffff & ~S_IFMT) | S_IFBLK;
        dev = (unsigned long) 0xdeadbeefbadc0ded;
 
-       rc = syscall(__NR_mknod, TMP_FILE, mode, dev);
-       printf("mknod(\"%s\", S_IFBLK|S_ISUID|S_ISGID|S_ISVTX|%#o"
+       rc = call_mknod(mode, dev);
+       printf("mknod(\"%s\", S_IFBLK|S_ISUID|S_ISGID|S_ISVTX|%#03ho"
               ", makedev(%u, %u)) = %ld %s (%m)\n",
-              TMP_FILE, (unsigned) mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX),
+              sample, mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX),
               major((unsigned) dev), minor((unsigned) dev),
               rc, errno2name());
 
index 2cdc47cf8828e4554b28a3121a8a86a7076a9d64..991bc4b2faba8ae637be96443b27c90c4398b020 100644 (file)
 #  include <sys/mkdev.h>
 # endif
 
+static const char sample[] = "mknodat_sample";
+static const long int fd = (long int) 0xdeadbeefffffffff;
+
+static long
+call_mknodat(unsigned short mode, unsigned long dev)
+{
+       unsigned long lmode = (unsigned long) 0xffffffffffff0000 | mode;
+       return syscall(__NR_mknodat, fd, sample, lmode, dev);
+}
+
 int
 main(void)
 {
-       static const char sample[] = "mknokat_sample";
-       const long int fd = (long int) 0xdeadbeefffffffff;
-       long rc = syscall(__NR_mknodat, fd, sample, S_IFREG|0600, 0);
-       printf("mknodat(%d, \"%s\", S_IFREG|0600) = %ld %s (%m)\n",
-              (int) fd, sample, rc, errno2name());
-
-       const unsigned long dev =
-               (unsigned long) 0xdeadbeef00000000 | makedev(1, 7);
-
-       rc = syscall(__NR_mknodat, fd, sample, S_IFCHR | 0400, dev);
-       printf("mknodat(%d, \"%s\", S_IFCHR|0400, makedev(1, 7)) = %ld %s (%m)\n",
-              (int) fd, sample, rc, errno2name());
+       unsigned long dev = (unsigned long) 0xdeadbeefbadc0ded;
+
+       long rc = call_mknodat(0, dev);
+       printf("mknodat(-1, \"%s\", 000) = %ld %s (%m)\n",
+              sample, rc, errno2name());
+
+       rc = call_mknodat(0xffff, dev);
+       printf("mknodat(-1, \"%s\", %#03ho) = %ld %s (%m)\n",
+              sample, (unsigned short) -1, rc, errno2name());
+
+       rc = call_mknodat(S_IFREG, 0);
+       printf("mknodat(-1, \"%s\", S_IFREG|000) = %ld %s (%m)\n",
+              sample, rc, errno2name());
+
+       rc = call_mknodat(S_IFDIR | 06, 0);
+       printf("mknodat(-1, \"%s\", S_IFDIR|006) = %ld %s (%m)\n",
+              sample, rc, errno2name());
+
+       rc = call_mknodat(S_IFLNK | 060, 0);
+       printf("mknodat(-1, \"%s\", S_IFLNK|060) = %ld %s (%m)\n",
+              sample, rc, errno2name());
+
+       rc = call_mknodat(S_IFIFO | 0600, 0);
+       printf("mknodat(-1, \"%s\", S_IFIFO|0600) = %ld %s (%m)\n",
+              sample, rc, errno2name());
+
+       dev = (unsigned long) 0xdeadbeef00000000 | makedev(1, 7);
+
+       rc = call_mknodat(S_IFCHR | 024, dev);
+       printf("mknodat(-1, \"%s\", S_IFCHR|024, makedev(1, 7)) = %ld %s (%m)\n",
+              sample, rc, errno2name());
+
+       const unsigned short mode = (0xffff & ~S_IFMT) | S_IFBLK;
+       dev = (unsigned long) 0xdeadbeefbadc0ded;
+
+       rc = call_mknodat(mode, dev);
+       printf("mknodat(-1, \"%s\", S_IFBLK|S_ISUID|S_ISGID|S_ISVTX|%#03ho"
+              ", makedev(%u, %u)) = %ld %s (%m)\n",
+              sample, mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX),
+              major((unsigned) dev), minor((unsigned) dev),
+              rc, errno2name());
 
        puts("+++ exited with 0 +++");
        return 0;
index edf0498b4693b2f32681c2052e972da22d9cb175..1701a368b9e9ccc8ca2715194c2a2dd3d1423c81 100755 (executable)
@@ -3,4 +3,4 @@
 # Check mknodat syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff
+run_strace_match_diff -a35
index 2dcea283a948d987baf44b52b666550dcf04612a..86903a954f1ed615131fb3289e9b5ab708eff428 100644 (file)
@@ -1,11 +1,23 @@
 #include <stdio.h>
 #include <sys/stat.h>
 
+void
+test_umask(const mode_t mode)
+{
+       mode_t rc = umask(0xffff0000 | mode);
+       printf("umask(%#03ho) = %#03o\n", (unsigned short) mode, rc);
+}
+
 int
 main(void)
 {
-       mode_t rc = umask(044);
-       printf("umask(%#o) = %#o\n", 044, rc);
+       test_umask(0);
+       test_umask(06);
+       test_umask(026);
+       test_umask(0126);
+       test_umask(07777);
+       test_umask(0107777);
+       test_umask(-1);
 
        puts("+++ exited with 0 +++");
        return 0;
diff --git a/tests/umode_t.c b/tests/umode_t.c
new file mode 100644 (file)
index 0000000..e9ece4b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Check decoding of umode_t type syscall arguments.
+ *
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#ifndef TEST_SYSCALL_PREFIX_ARGS
+# define TEST_SYSCALL_PREFIX_ARGS
+#endif
+#ifndef TEST_SYSCALL_PREFIX_STR
+# define TEST_SYSCALL_PREFIX_STR ""
+#endif
+
+static const char sample[] = TEST_SYSCALL_STR;
+
+static void
+test_syscall(unsigned short mode)
+{
+       unsigned long lmode = (unsigned long) 0xffffffffffff0000 | mode;
+       long rc = syscall(TEST_SYSCALL_NR, TEST_SYSCALL_PREFIX_ARGS
+                         sample, lmode);
+
+       printf("%s(%s\"%s\", %#03ho) = %ld %s (%m)\n",
+              sample, TEST_SYSCALL_PREFIX_STR, sample, mode, rc, errno2name());
+}
+
+int
+main(void)
+{
+       test_syscall(0);
+       test_syscall(0xffff);
+       test_syscall(06);
+       test_syscall(060);
+       test_syscall(0600);
+       test_syscall(024);
+       test_syscall(S_IFREG);
+       test_syscall(S_IFDIR | 06);
+       test_syscall(S_IFLNK | 060);
+       test_syscall(S_IFIFO | 0600);
+       test_syscall(S_IFCHR | 024);
+       test_syscall((0xffff & ~S_IFMT) | S_IFBLK);
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}
diff --git a/umask.c b/umask.c
index dda40d4a0cf99f050fb572b2ab48dbbff9763fce..d42258a9618de4ee17ee24a9b3475ba0380bf90a 100644 (file)
--- a/umask.c
+++ b/umask.c
@@ -2,7 +2,7 @@
 
 SYS_FUNC(umask)
 {
-       tprintf("%#lo", tcp->u_arg[0]);
+       print_numeric_umode_t(tcp->u_arg[0]);
 
        return RVAL_DECODED | RVAL_OCTAL;
 }