1 /*
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-1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 2006 Ulrich Drepper <drepper@redhat.com>
7 * Copyright (c) 2006 Bernhard Kaindl <bk@suse.de>
8 * Copyright (c) 2006-2015 Dmitry V. Levin <ldv@strace.io>
9 * Copyright (c) 2014-2021 The strace developers.
10 * All rights reserved.
11 *
12 * SPDX-License-Identifier: LGPL-2.1-or-later
13 */
14
15 #include "defs.h"
16
17 static int
18 decode_readlink(struct tcb *tcp, int offset)
19 {
20 if (entering(tcp)) {
21 /* pathname */
22 printpath(tcp, tcp->u_arg[offset]);
23 tprint_arg_next();
24 } else {
25 /* buf */
26 if (syserror(tcp))
27 printaddr(tcp->u_arg[offset + 1]);
28 else
29 /* Used to use printpathn(), but readlink
30 * neither includes NUL in the returned count,
31 * nor actually writes it into memory.
32 * printpathn() would decide on printing
33 * "..." continuation based on garbage
34 * past return buffer's end.
35 */
36 printstrn(tcp, tcp->u_arg[offset + 1], tcp->u_rval);
37 tprint_arg_next();
38
39 /* bufsiz */
40 PRINT_VAL_U(tcp->u_arg[offset + 2]);
41 }
42 return 0;
43 }
44
45 SYS_FUNC(readlink)
46 {
47 return decode_readlink(tcp, 0);
48 }
49
50 SYS_FUNC(readlinkat)
51 {
52 if (entering(tcp)) {
53 /* dirfd */
54 print_dirfd(tcp, tcp->u_arg[0]);
55 tprint_arg_next();
56 }
57 return decode_readlink(tcp, 1);
58 }