]> granicus.if.org Git - strace/blob - sysctl.c
io.c: move sendfile parsers to a separate file
[strace] / sysctl.c
1 #include "defs.h"
2
3 #include <linux/sysctl.h>
4
5 #include "xlat/sysctl_root.h"
6 #include "xlat/sysctl_kern.h"
7 #include "xlat/sysctl_vm.h"
8 #include "xlat/sysctl_net.h"
9 #include "xlat/sysctl_net_core.h"
10 #include "xlat/sysctl_net_unix.h"
11 #include "xlat/sysctl_net_ipv4.h"
12 #include "xlat/sysctl_net_ipv4_route.h"
13 #include "xlat/sysctl_net_ipv4_conf.h"
14 #include "xlat/sysctl_net_ipv6.h"
15 #include "xlat/sysctl_net_ipv6_route.h"
16
17 SYS_FUNC(sysctl)
18 {
19         struct __sysctl_args info;
20         int *name;
21         unsigned long size;
22
23         if (umove_or_printaddr(tcp, tcp->u_arg[0], &info))
24                 return RVAL_DECODED;
25
26         size = sizeof(int) * (unsigned long) info.nlen;
27         name = (size / sizeof(int) != (unsigned long) info.nlen) ? NULL : malloc(size);
28         if (name == NULL ||
29             umoven(tcp, (unsigned long) info.name, size, name) < 0) {
30                 free(name);
31                 if (entering(tcp))
32                         tprintf("{%p, %d, %p, %p, %p, %lu}",
33                                 info.name, info.nlen, info.oldval,
34                                 info.oldlenp, info.newval, (unsigned long)info.newlen);
35                 return RVAL_DECODED;
36         }
37
38         if (entering(tcp)) {
39                 unsigned int cnt = 0, max_cnt;
40
41                 tprints("{{");
42
43                 if (info.nlen == 0)
44                         goto out;
45                 printxval(sysctl_root, name[0], "CTL_???");
46                 ++cnt;
47
48                 if (info.nlen == 1)
49                         goto out;
50                 switch (name[0]) {
51                 case CTL_KERN:
52                         tprints(", ");
53                         printxval(sysctl_kern, name[1], "KERN_???");
54                         ++cnt;
55                         break;
56                 case CTL_VM:
57                         tprints(", ");
58                         printxval(sysctl_vm, name[1], "VM_???");
59                         ++cnt;
60                         break;
61                 case CTL_NET:
62                         tprints(", ");
63                         printxval(sysctl_net, name[1], "NET_???");
64                         ++cnt;
65
66                         if (info.nlen == 2)
67                                 goto out;
68                         switch (name[1]) {
69                         case NET_CORE:
70                                 tprints(", ");
71                                 printxval(sysctl_net_core, name[2],
72                                           "NET_CORE_???");
73                                 break;
74                         case NET_UNIX:
75                                 tprints(", ");
76                                 printxval(sysctl_net_unix, name[2],
77                                           "NET_UNIX_???");
78                                 break;
79                         case NET_IPV4:
80                                 tprints(", ");
81                                 printxval(sysctl_net_ipv4, name[2],
82                                           "NET_IPV4_???");
83
84                                 if (info.nlen == 3)
85                                         goto out;
86                                 switch (name[2]) {
87                                 case NET_IPV4_ROUTE:
88                                         tprints(", ");
89                                         printxval(sysctl_net_ipv4_route,
90                                                   name[3],
91                                                   "NET_IPV4_ROUTE_???");
92                                         break;
93                                 case NET_IPV4_CONF:
94                                         tprints(", ");
95                                         printxval(sysctl_net_ipv4_conf,
96                                                   name[3],
97                                                   "NET_IPV4_CONF_???");
98                                         break;
99                                 default:
100                                         goto out;
101                                 }
102                                 break;
103                         case NET_IPV6:
104                                 tprints(", ");
105                                 printxval(sysctl_net_ipv6, name[2],
106                                           "NET_IPV6_???");
107
108                                 if (info.nlen == 3)
109                                         goto out;
110                                 switch (name[2]) {
111                                 case NET_IPV6_ROUTE:
112                                         tprints(", ");
113                                         printxval(sysctl_net_ipv6_route,
114                                                   name[3],
115                                                   "NET_IPV6_ROUTE_???");
116                                         break;
117                                 default:
118                                         goto out;
119                                 }
120                                 break;
121                         default:
122                                 goto out;
123                         }
124                         break;
125                 default:
126                         goto out;
127                 }
128         out:
129                 max_cnt = info.nlen;
130                 if (abbrev(tcp) && max_cnt > max_strlen)
131                         max_cnt = max_strlen;
132                 while (cnt < max_cnt)
133                         tprintf(", %x", name[cnt++]);
134                 if (cnt < (unsigned) info.nlen)
135                         tprints(", ...");
136                 tprintf("}, %d, ", info.nlen);
137         } else {
138                 size_t oldlen = 0;
139                 if (info.oldval == NULL) {
140                         tprints("NULL");
141                 } else if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0
142                            && info.nlen >= 2
143                            && ((name[0] == CTL_KERN
144                                 && (name[1] == KERN_OSRELEASE
145                                     || name[1] == KERN_OSTYPE
146                                         )))) {
147                         printpath(tcp, (size_t)info.oldval);
148                 } else {
149                         tprintf("%p", info.oldval);
150                 }
151                 tprintf(", %lu, ", (unsigned long)oldlen);
152                 if (info.newval == NULL)
153                         tprints("NULL");
154                 else if (syserror(tcp))
155                         tprintf("%p", info.newval);
156                 else
157                         printpath(tcp, (size_t)info.newval);
158                 tprintf(", %lu", (unsigned long)info.newlen);
159         }
160
161         free(name);
162         return 0;
163 }