1 /*
2 * Copyright (c) 2004 Ulrich Drepper <drepper@redhat.com>
3 * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@strace.io>
4 * Copyright (c) 2015-2021 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: LGPL-2.1-or-later
8 */
9
10 #include "defs.h"
11 #include <fcntl.h>
12
13 SYS_FUNC(mq_open)
14 {
15 /* name */
16 printpath(tcp, tcp->u_arg[0]);
17 tprint_arg_next();
18
19 /* flags */
20 tprint_open_modes(tcp->u_arg[1]);
21
22 if (tcp->u_arg[1] & O_CREAT) {
23 tprint_arg_next();
24
25 /* mode */
26 print_numeric_umode_t(tcp->u_arg[2]);
27 tprint_arg_next();
28
29 /* attr */
30 printmqattr(tcp, tcp->u_arg[3], false);
31 }
32 return RVAL_DECODED | RVAL_FD;
33 }
34
35 static int
36 do_mq_timedsend(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
37 {
38 /* mqdes */
39 printfd(tcp, tcp->u_arg[0]);
40 tprint_arg_next();
41
42 /* msg_ptr */
43 printstrn(tcp, tcp->u_arg[1], tcp->u_arg[2]);
44 tprint_arg_next();
45
46 /* msg_len */
47 PRINT_VAL_U(tcp->u_arg[2]);
48 tprint_arg_next();
49
50 /* msg_prio */
51 PRINT_VAL_U((unsigned int) tcp->u_arg[3]);
52 tprint_arg_next();
53
54 /* abs_timeout */
55 print_ts(tcp, tcp->u_arg[4]);
56
57 return RVAL_DECODED;
58 }
59
60 #if HAVE_ARCH_TIME32_SYSCALLS
61 SYS_FUNC(mq_timedsend_time32)
62 {
63 return do_mq_timedsend(tcp, print_timespec32);
64 }
65 #endif
66
67 SYS_FUNC(mq_timedsend_time64)
68 {
69 return do_mq_timedsend(tcp, print_timespec64);
70 }
71
72 static int
73 do_mq_timedreceive(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
74 {
75 if (entering(tcp)) {
76 /* mqdes */
77 printfd(tcp, tcp->u_arg[0]);
78 tprint_arg_next();
79 } else {
80 /* msg_ptr */
81 if (syserror(tcp))
82 printaddr(tcp->u_arg[1]);
83 else
84 printstrn(tcp, tcp->u_arg[1], tcp->u_rval);
85 tprint_arg_next();
86
87 /* msg_len */
88 PRINT_VAL_U(tcp->u_arg[2]);
89 tprint_arg_next();
90
91 printnum_int(tcp, tcp->u_arg[3], "%u");
92 tprint_arg_next();
93
94 /*
95 * Since the timeout parameter is read by the kernel
96 * on entering syscall, it has to be decoded the same way
97 * whether the syscall has failed or not.
98 */
99 temporarily_clear_syserror(tcp);
100 /* abs_timeout */
101 print_ts(tcp, tcp->u_arg[4]);
102 restore_cleared_syserror(tcp);
103 }
104 return 0;
105 }
106
107 #if HAVE_ARCH_TIME32_SYSCALLS
108 SYS_FUNC(mq_timedreceive_time32)
109 {
110 return do_mq_timedreceive(tcp, print_timespec32);
111 }
112 #endif
113
114 SYS_FUNC(mq_timedreceive_time64)
115 {
116 return do_mq_timedreceive(tcp, print_timespec64);
117 }
118
119 SYS_FUNC(mq_notify)
120 {
121 /* mqdes */
122 printfd(tcp, tcp->u_arg[0]);
123 tprint_arg_next();
124
125 /* sevp */
126 print_sigevent(tcp, tcp->u_arg[1]);
127 return RVAL_DECODED;
128 }
129
130 SYS_FUNC(mq_getsetattr)
131 {
132 if (entering(tcp)) {
133 /* mqdes */
134 printfd(tcp, tcp->u_arg[0]);
135 tprint_arg_next();
136
137 /* newattr */
138 printmqattr(tcp, tcp->u_arg[1], true);
139 tprint_arg_next();
140 } else {
141 /* oldattr */
142 printmqattr(tcp, tcp->u_arg[2], true);
143 }
144 return 0;
145 }