Branch data Line data Source code
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, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 : : * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 : : * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
7 : : * Copyright (c) 2015-2017 The strace developers.
8 : : * All rights reserved.
9 : : *
10 : : * Redistribution and use in source and binary forms, with or without
11 : : * modification, are permitted provided that the following conditions
12 : : * are met:
13 : : * 1. Redistributions of source code must retain the above copyright
14 : : * notice, this list of conditions and the following disclaimer.
15 : : * 2. Redistributions in binary form must reproduce the above copyright
16 : : * notice, this list of conditions and the following disclaimer in the
17 : : * documentation and/or other materials provided with the distribution.
18 : : * 3. The name of the author may not be used to endorse or promote products
19 : : * derived from this software without specific prior written permission.
20 : : *
21 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : : */
32 : :
33 : : #include "defs.h"
34 : : #include <dirent.h>
35 : :
36 : : #include "xlat/dirent_types.h"
37 : :
38 : : #define D_NAME_LEN_MAX 256
39 : :
40 : 12 : SYS_FUNC(getdents64)
41 : : {
42 : : /* the minimum size of a valid dirent64 structure */
43 : 12 : const unsigned int d_name_offset = offsetof(struct dirent64, d_name);
44 : :
45 : 12 : unsigned int i, len, dents = 0;
46 : : char *buf;
47 : :
48 [ + + ]: 12 : if (entering(tcp)) {
49 : 6 : printfd(tcp, tcp->u_arg[0]);
50 : 6 : return 0;
51 : : }
52 : :
53 : 6 : const unsigned int count = tcp->u_arg[2];
54 : :
55 [ + + ][ - + ]: 6 : if (syserror(tcp) || !verbose(tcp)) {
56 : 2 : tprints(", ");
57 : 2 : printaddr(tcp->u_arg[1]);
58 : 2 : tprintf(", %u", count);
59 : 2 : return 0;
60 : : }
61 : :
62 : : /* Beware of insanely large or too small values in tcp->u_rval */
63 [ + - ]: 4 : if (tcp->u_rval > 1024*1024)
64 : : len = 1024*1024;
65 [ + + ]: 4 : else if (tcp->u_rval < (int) d_name_offset)
66 : : len = 0;
67 : : else
68 : 2 : len = tcp->u_rval;
69 : :
70 [ + + ]: 4 : if (len) {
71 : 2 : buf = malloc(len);
72 [ + - ][ - + ]: 2 : if (!buf || umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
73 : 0 : tprints(", ");
74 : 0 : printaddr(tcp->u_arg[1]);
75 : 0 : tprintf(", %u", count);
76 : 0 : free(buf);
77 : 0 : return 0;
78 : : }
79 : : } else {
80 : : buf = NULL;
81 : : }
82 : :
83 : 4 : tprints(",");
84 [ + - ]: 4 : if (!abbrev(tcp))
85 : 4 : tprints(" [");
86 [ + + ][ + + ]: 10 : for (i = 0; len && i <= len - d_name_offset; ) {
87 : 6 : struct dirent64 *d = (struct dirent64 *) &buf[i];
88 [ + - ]: 6 : if (!abbrev(tcp)) {
89 : : int d_name_len;
90 [ + - ]: 6 : if (d->d_reclen >= d_name_offset
91 [ + - ]: 6 : && i + d->d_reclen <= len) {
92 : 6 : d_name_len = d->d_reclen - d_name_offset;
93 : : } else {
94 : 0 : d_name_len = len - i - d_name_offset;
95 : : }
96 [ + + ]: 6 : if (d_name_len > D_NAME_LEN_MAX)
97 : 2 : d_name_len = D_NAME_LEN_MAX;
98 : :
99 [ + + ]: 6 : tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64
100 : : ", d_reclen=%u, d_type=",
101 : : i ? ", " : "",
102 : : d->d_ino,
103 : : d->d_off,
104 : : d->d_reclen);
105 : 6 : printxval(dirent_types, d->d_type, "DT_???");
106 : :
107 : 6 : tprints(", d_name=");
108 : 6 : print_quoted_cstring(d->d_name, d_name_len);
109 : :
110 : 6 : tprints("}");
111 : : }
112 [ - + ]: 6 : if (d->d_reclen < d_name_offset) {
113 : 0 : tprints_comment("d_reclen < offsetof(struct dirent64, d_name)");
114 : 0 : break;
115 : : }
116 : 6 : i += d->d_reclen;
117 : 6 : dents++;
118 : : }
119 [ + - ]: 4 : if (!abbrev(tcp))
120 : 4 : tprints("]");
121 : : else
122 : 0 : tprintf_comment("%u entries", dents);
123 : 4 : tprintf(", %u", count);
124 : 4 : free(buf);
125 : 4 : return 0;
126 : : }
|