]> granicus.if.org Git - strace/blob - io.c
Merge changes from Ulrich
[strace] / io.c
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  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  *      $Id$
31  */
32
33 #include "defs.h"
34
35 #include <fcntl.h>
36 #include <sys/uio.h>
37
38 int
39 sys_read(tcp)
40 struct tcb *tcp;
41 {
42         if (entering(tcp)) {
43                 tprintf("%ld, ", tcp->u_arg[0]);
44         } else {
45                 if (syserror(tcp))
46                         tprintf("%#lx", tcp->u_arg[1]);
47                 else
48                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
49                 tprintf(", %lu", tcp->u_arg[2]);
50         }
51         return 0;
52 }
53
54 int
55 sys_write(tcp)
56 struct tcb *tcp;
57 {
58         if (entering(tcp)) {
59                 tprintf("%ld, ", tcp->u_arg[0]);
60                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
61                 tprintf(", %lu", tcp->u_arg[2]);
62         }
63         return 0;
64 }
65
66 int
67 sys_readv(tcp)
68 struct tcb *tcp;
69 {
70         struct iovec *iov;
71         int i, len;
72
73         if (entering(tcp)) {
74                 tprintf("%ld, ", tcp->u_arg[0]);
75         } else {
76                 if (syserror(tcp)) {
77                         tprintf("%#lx, %lu",
78                                         tcp->u_arg[1], tcp->u_arg[2]);
79                         return 0;
80                 }
81                 len = tcp->u_arg[2];
82                 if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
83                         fprintf(stderr, "No memory");
84                         return 0;
85                 }
86                 if (umoven(tcp, tcp->u_arg[1],
87                                 len * sizeof *iov, (char *) iov) < 0) {
88                         tprintf("%#lx", tcp->u_arg[1]);
89                 } else {
90                         tprintf("[");
91                         for (i = 0; i < len; i++) {
92                                 if (i)
93                                         tprintf(", ");
94                                 tprintf("{");
95                                 printstr(tcp, (long) iov[i].iov_base,
96                                         iov[i].iov_len);
97                                 tprintf(", %lu}", (unsigned long)iov[i].iov_len);
98                         }
99                         tprintf("]");
100                 }
101                 free((char *) iov);
102                 tprintf(", %lu", tcp->u_arg[2]);
103         }
104         return 0;
105 }
106
107 int
108 sys_writev(tcp)
109 struct tcb *tcp;
110 {
111         struct iovec *iov;
112         int i, len;
113
114         if (entering(tcp)) {
115                 tprintf("%ld, ", tcp->u_arg[0]);
116                 len = tcp->u_arg[2];
117                 iov = (struct iovec *) malloc(len * sizeof *iov);
118                 if (iov == NULL) {
119                         fprintf(stderr, "No memory");
120                         return 0;
121                 }
122                 if (umoven(tcp, tcp->u_arg[1],
123                                 len * sizeof *iov, (char *) iov) < 0) {
124                         tprintf("%#lx", tcp->u_arg[1]);
125                 } else {
126                         tprintf("[");
127                         for (i = 0; i < len; i++) {
128                                 if (i)
129                                         tprintf(", ");
130                                 tprintf("{");
131                                 printstr(tcp, (long) iov[i].iov_base,
132                                         iov[i].iov_len);
133                                 tprintf(", %lu}", (unsigned long)iov[i].iov_len);
134                         }
135                         tprintf("]");
136                 }
137                 free((char *) iov);
138                 tprintf(", %lu", tcp->u_arg[2]);
139         }
140         return 0;
141 }
142
143 #ifdef SVR4
144
145 int
146 sys_pread(tcp)
147 struct tcb *tcp;
148 {
149         if (entering(tcp)) {
150                 tprintf("%ld, ", tcp->u_arg[0]);
151         } else {
152                 if (syserror(tcp))
153                         tprintf("%#lx", tcp->u_arg[1]);
154                 else
155                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
156 #if UNIXWARE
157                 /* off_t is signed int */
158                 tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]);
159 #else
160                 tprintf(", %lu, %llu", tcp->u_arg[2],
161                                 (((unsigned long long) tcp->u_arg[4]) << 32
162                                  | tcp->u_arg[3]));
163 #endif
164         }
165         return 0;
166 }
167
168 int
169 sys_pwrite(tcp)
170 struct tcb *tcp;
171 {
172         if (entering(tcp)) {
173                 tprintf("%ld, ", tcp->u_arg[0]);
174                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
175 #if UNIXWARE
176                 /* off_t is signed int */
177                 tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]);
178 #else
179                 tprintf(", %lu, %llu", tcp->u_arg[2],
180                                 (((unsigned long long) tcp->u_arg[4]) << 32
181                                  | tcp->u_arg[3]));
182 #endif
183         }
184         return 0;
185 }
186 #endif /* SVR4 */
187
188 #ifdef LINUX
189 int
190 sys_pread(tcp)
191 struct tcb *tcp;
192 {
193         if (entering(tcp)) {
194                 tprintf("%ld, ", tcp->u_arg[0]);
195         } else {
196                 if (syserror(tcp))
197                         tprintf("%#lx", tcp->u_arg[1]);
198                 else
199                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
200                 tprintf(", %lu, %llu", tcp->u_arg[2],
201                         *(unsigned long long *)&tcp->u_arg[3]);
202         }
203         return 0;
204 }
205
206 int
207 sys_pwrite(tcp)
208 struct tcb *tcp;
209 {
210         if (entering(tcp)) {
211                 tprintf("%ld, ", tcp->u_arg[0]);
212                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
213                 tprintf(", %lu, %llu", tcp->u_arg[2],
214                         *(unsigned long long *)&tcp->u_arg[3]);
215         }
216         return 0;
217 }
218
219 int
220 sys_sendfile(tcp)
221 struct tcb *tcp;
222 {
223         if (entering(tcp)) {
224                 off_t offset;
225
226                 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
227                 if (!tcp->u_arg[2])
228                         tprintf("NULL");
229                 else if (umove(tcp, tcp->u_arg[2], &offset) < 0)
230                         tprintf("%#lx", tcp->u_arg[2]);
231                 else
232                         tprintf("[%lu]", offset);
233                 tprintf(", %lu", tcp->u_arg[3]);
234         }
235         return 0;
236 }
237
238 #endif /* LINUX */
239
240 int
241 sys_ioctl(tcp)
242 struct tcb *tcp;
243 {
244         char *symbol;
245
246         if (entering(tcp)) {
247                 tprintf("%ld, ", tcp->u_arg[0]);
248                 symbol = ioctl_lookup(tcp->u_arg[1]);
249                 if (symbol)
250                         tprintf("%s", symbol);
251                 else
252                         tprintf("%#lx", tcp->u_arg[1]);
253                 ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]);
254         }
255         else {
256                 if (ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]) == 0)
257                         tprintf(", %#lx", tcp->u_arg[2]);
258         }
259         return 0;
260 }