2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999-2019 The strace developers.
9 * SPDX-License-Identifier: LGPL-2.1-or-later
17 printfd(tcp, tcp->u_arg[0]);
24 printfd(tcp, tcp->u_arg[0]);
26 return RVAL_DECODED | RVAL_FD;
30 do_dup2(struct tcb *tcp, int flags_arg)
32 printfd(tcp, tcp->u_arg[0]);
34 printfd(tcp, tcp->u_arg[1]);
37 printflags(open_mode_flags, tcp->u_arg[flags_arg], "O_???");
40 return RVAL_DECODED | RVAL_FD;
45 return do_dup2(tcp, -1);
50 return do_dup2(tcp, 2);
54 decode_select(struct tcb *const tcp, const kernel_ulong_t *const args,
55 const print_obj_by_addr_fn print_tv_ts,
56 const sprint_obj_by_addr_fn sprint_tv_ts)
64 /* Kernel truncates args[0] to int, we do the same. */
67 /* Kernel rejects negative nfds, so we don't parse it either. */
71 /* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
76 * We had bugs a-la "while (j < args[0])" and "umoven(args[0])" below.
77 * Instead of args[0], use nfds for fd count, fdsize for array lengths.
79 fdsize = (((nfds + 7) / 8) + current_wordsize-1) & -current_wordsize;
82 tprintf("%d", (int) args[0]);
84 if (verbose(tcp) && fdsize > 0)
86 for (i = 0; i < 3; i++) {
93 if (umoven_or_printaddr(tcp, addr, fdsize, fds))
96 for (j = 0, sep = "";; j++) {
97 j = next_set_bit(fds, j, nfds);
108 print_tv_ts(tcp, args[4]);
110 static char outstr[1024];
112 #define end_outstr (outstr + sizeof(outstr))
118 ready_fds = tcp->u_rval;
119 if (ready_fds == 0) {
120 tcp->auxstr = "Timeout";
124 fds = malloc(fdsize);
128 for (i = 0; i < 3 && ready_fds > 0; i++) {
132 if (!addr || !fds || umoven(tcp, addr, fdsize, fds) < 0)
135 j = next_set_bit(fds, j, nfds);
138 /* +2 chars needed at the end: ']',NUL */
139 if (outptr < end_outstr - (sizeof(", except [") + sizeof(int)*3 + 2)) {
141 outptr = xappendstr(outstr,
145 i == 0 ? "in" : i == 1 ? "out" : "except",
151 outptr = xappendstr(outstr,
156 if (--ready_fds == 0)
159 if (outptr != outstr)
163 /* This contains no useful information on SunOS. */
165 const char *str = sprint_tv_ts(tcp, args[4]);
166 if (outptr + sizeof("left ") + strlen(sep) + strlen(str) < end_outstr) {
167 outptr = xappendstr(outstr, outptr,
168 "%sleft %s", sep, str);
172 tcp->auxstr = outstr;
179 #if HAVE_ARCH_OLD_SELECT
182 kernel_ulong_t *args =
183 fetch_indirect_syscall_args(tcp, tcp->u_arg[0], 5);
186 return decode_select(tcp, args, print_timeval, sprint_timeval);
189 printaddr(tcp->u_arg[0]);
193 #endif /* HAVE_ARCH_OLD_SELECT */
198 return decode_select(tcp, tcp->u_arg, print_timeval32, sprint_timeval32);
204 return decode_select(tcp, tcp->u_arg, print_timeval, sprint_timeval);
208 umove_kulong_array_or_printaddr(struct tcb *const tcp, const kernel_ulong_t addr,
209 kernel_ulong_t *const ptr, const size_t n)
211 #ifndef current_klongsize
212 if (current_klongsize < sizeof(*ptr)) {
214 int r = umove_or_printaddr(tcp, addr, &ptr32);
218 for (i = 0; i < n; ++i)
223 #endif /* !current_klongsize */
224 return umoven_or_printaddr(tcp, addr, n * sizeof(*ptr), ptr);
228 do_pselect6(struct tcb *const tcp, const print_obj_by_addr_fn print_ts,
229 const sprint_obj_by_addr_fn sprint_ts)
231 int rc = decode_select(tcp, tcp->u_arg, print_ts, sprint_ts);
233 kernel_ulong_t data[2];
236 if (!umove_kulong_array_or_printaddr(tcp, tcp->u_arg[5],
237 data, ARRAY_SIZE(data))) {
239 /* NB: kernel requires data[1] == NSIG_BYTES */
240 print_sigset_addr_len(tcp, data[0], data[1]);
241 tprintf(", %" PRI_klu "}", data[1]);
248 #if HAVE_ARCH_TIME32_SYSCALLS
249 SYS_FUNC(pselect6_time32)
251 return do_pselect6(tcp, print_timespec32, sprint_timespec32);
255 SYS_FUNC(pselect6_time64)
257 return do_pselect6(tcp, print_timespec64, sprint_timespec64);