desc.c revision 4dc8a2aec63e4fb5ee2688544c4de323ed5de3ef
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/file.h> 37 38static struct xlat fcntlcmds[] = { 39 { F_DUPFD, "F_DUPFD" }, 40 { F_GETFD, "F_GETFD" }, 41 { F_SETFD, "F_SETFD" }, 42 { F_GETFL, "F_GETFL" }, 43 { F_SETFL, "F_SETFL" }, 44 { F_GETLK, "F_GETLK" }, 45 { F_SETLK, "F_SETLK" }, 46 { F_SETLKW, "F_SETLKW" }, 47 { F_GETOWN, "F_GETOWN" }, 48 { F_SETOWN, "F_SETOWN" }, 49#ifdef F_RSETLK 50 { F_RSETLK, "F_RSETLK" }, 51#endif 52#ifdef F_RSETLKW 53 { F_RSETLKW, "F_RSETLKW" }, 54#endif 55#ifdef F_RGETLK 56 { F_RGETLK, "F_RGETLK" }, 57#endif 58#ifdef F_CNVT 59 { F_CNVT, "F_CNVT" }, 60#endif 61 { 0, NULL }, 62}; 63 64static struct xlat fdflags[] = { 65#ifdef FD_CLOEXEC 66 { FD_CLOEXEC, "FD_CLOEXEC" }, 67#endif 68 { 0, NULL }, 69}; 70 71#ifdef LOCK_SH 72 73static struct xlat flockcmds[] = { 74 { LOCK_SH, "LOCK_SH" }, 75 { LOCK_EX, "LOCK_EX" }, 76 { LOCK_NB, "LOCK_NB" }, 77 { LOCK_UN, "LOCK_UN" }, 78 { 0, NULL }, 79}; 80 81#endif /* LOCK_SH */ 82 83static struct xlat lockfcmds[] = { 84 { F_RDLCK, "F_RDLCK" }, 85 { F_WRLCK, "F_WRLCK" }, 86 { F_UNLCK, "F_UNLCK" }, 87#ifdef F_EXLCK 88 { F_EXLCK, "F_EXLCK" }, 89#endif 90#ifdef F_SHLCK 91 { F_SHLCK, "F_SHLCK" }, 92#endif 93 { 0, NULL }, 94}; 95 96static struct xlat whence[] = { 97 { SEEK_SET, "SEEK_SET" }, 98 { SEEK_CUR, "SEEK_CUR" }, 99 { SEEK_END, "SEEK_END" }, 100 { 0, NULL }, 101}; 102 103/* fcntl/lockf */ 104static void 105printflock(tcp, addr, getlk) 106struct tcb *tcp; 107int addr; 108int getlk; 109{ 110 struct flock fl; 111 112 if (umove(tcp, addr, &fl) < 0) { 113 tprintf("{...}"); 114 return; 115 } 116 tprintf("{type="); 117 printxval(lockfcmds, fl.l_type, "F_???"); 118 tprintf(", whence="); 119 printxval(whence, fl.l_whence, "SEEK_???"); 120 tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len); 121 if (getlk) 122 tprintf(", pid=%lu}", (unsigned long) fl.l_pid); 123 else 124 tprintf("}"); 125} 126 127static char * 128sprintflags(xlat, flags) 129struct xlat *xlat; 130int flags; 131{ 132 static char outstr[1024]; 133 char *sep; 134 135 strcpy(outstr, "flags "); 136 sep = ""; 137 for (; xlat->str; xlat++) { 138 if ((flags & xlat->val) == xlat->val) { 139 sprintf(outstr + strlen(outstr), 140 "%s%s", sep, xlat->str); 141 sep = "|"; 142 flags &= ~xlat->val; 143 } 144 } 145 if (flags) 146 sprintf(outstr + strlen(outstr), 147 "%s%#x", sep, flags); 148 return outstr; 149} 150 151int 152sys_fcntl(tcp) 153struct tcb *tcp; 154{ 155 extern struct xlat openmodes[]; 156 157 if (entering(tcp)) { 158 tprintf("%ld, ", tcp->u_arg[0]); 159 printxval(fcntlcmds, tcp->u_arg[1], "F_???"); 160 switch (tcp->u_arg[1]) { 161 case F_SETFD: 162 tprintf(", "); 163 if (printflags(fdflags, tcp->u_arg[2]) == 0) 164 tprintf("0"); 165 break; 166 case F_SETOWN: case F_DUPFD: 167 tprintf(", %ld", tcp->u_arg[2]); 168 break; 169 case F_SETFL: 170 tprintf(", "); 171 if (printflags(openmodes, tcp->u_arg[2] + 1) == 0) 172 tprintf("0"); 173 break; 174 case F_SETLK: case F_SETLKW: 175 tprintf(", "); 176 printflock(tcp, tcp->u_arg[2], 0); 177 break; 178 } 179 } 180 else { 181 switch (tcp->u_arg[1]) { 182 case F_DUPFD: 183 case F_SETFD: case F_SETFL: 184 case F_SETLK: case F_SETLKW: 185 case F_SETOWN: case F_GETOWN: 186 break; 187 case F_GETFD: 188 if (tcp->u_rval == 0) 189 return 0; 190 tcp->auxstr = sprintflags(fdflags, tcp->u_rval); 191 return RVAL_HEX|RVAL_STR; 192 case F_GETFL: 193 tcp->auxstr = sprintflags(openmodes, tcp->u_rval + 1); 194 return RVAL_HEX|RVAL_STR; 195 case F_GETLK: 196 tprintf(", "); 197 printflock(tcp, tcp->u_arg[2], 1); 198 break; 199 default: 200 tprintf(", %#lx", tcp->u_arg[2]); 201 break; 202 } 203 } 204 return 0; 205} 206 207#ifdef LOCK_SH 208 209int 210sys_flock(tcp) 211struct tcb *tcp; 212{ 213 if (entering(tcp)) { 214 tprintf("%ld, ", tcp->u_arg[0]); 215 if (!printflags(flockcmds, tcp->u_arg[1])) 216 tprintf("LOCK_???"); 217 } 218 return 0; 219} 220#endif /* LOCK_SH */ 221 222int 223sys_close(tcp) 224struct tcb *tcp; 225{ 226 if (entering(tcp)) { 227 tprintf("%ld", tcp->u_arg[0]); 228 } 229 return 0; 230} 231 232int 233sys_dup(tcp) 234struct tcb *tcp; 235{ 236 if (entering(tcp)) { 237 tprintf("%ld", tcp->u_arg[0]); 238 } 239 return 0; 240} 241 242int 243sys_dup2(tcp) 244struct tcb *tcp; 245{ 246 if (entering(tcp)) { 247 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]); 248 } 249 return 0; 250} 251 252int 253sys_getdtablesize(tcp) 254struct tcb *tcp; 255{ 256 return 0; 257} 258 259static int 260decode_select(tcp, args, bitness) 261struct tcb *tcp; 262long *args; 263int bitness; 264{ 265 int i, j, nfds; 266 fd_set fds; 267 struct timeval tv; 268#ifdef ALPHA 269 struct timeval32 { 270 unsigned tv_sec; 271 unsigned tv_usec; 272 } *tv32; 273#endif 274 static char outstr[1024]; 275 char *sep; 276 long arg; 277 278 if (entering(tcp)) { 279 nfds = args[0]; 280 tprintf("%d", nfds); 281 for (i = 0; i < 3; i++) { 282 arg = args[i+1]; 283 if (arg == 0) { 284 tprintf(", NULL"); 285 continue; 286 } 287 if (!verbose(tcp)) { 288 tprintf(", %#lx", arg); 289 continue; 290 } 291 if (umove(tcp, arg, &fds) < 0) { 292 tprintf(", [?]"); 293 continue; 294 } 295 tprintf(", ["); 296 for (j = 0, sep = ""; j < nfds; j++) { 297 if (FD_ISSET(j, &fds)) { 298 tprintf("%s%u", sep, j); 299 sep = " "; 300 } 301 } 302 tprintf("]"); 303 } 304 if (!args[4]) 305 tprintf(", NULL"); 306 else if (!verbose(tcp)) 307 tprintf(", %#lx", args[4]); 308 else if (umove(tcp, args[4], &tv) < 0) 309 tprintf(", {...}"); 310 else { 311#ifdef ALPHA 312 if (bitness) { 313 tv32=(struct timeval32*)&tv; 314 tprintf(", {%u, %u}", tv32->tv_sec, tv32->tv_usec); 315 } else 316#endif 317 tprintf(", {%lu, %lu}", 318 (long) tv.tv_sec, (long) tv.tv_usec); 319 } 320 } 321 else 322 { 323 unsigned int cumlen = 0; 324 char *sep = ""; 325 326 if (syserror(tcp)) 327 return 0; 328 329 if ((nfds = tcp->u_rval) == 0) { 330 tcp->auxstr = "Timeout"; 331 return RVAL_STR; 332 } 333 outstr[0] = '\0'; 334 for (i = 0; i < 3; i++) { 335 int first = 1; 336 char str[20]; 337 338 tcp->auxstr = outstr; 339 arg = args[i+1]; 340 if (!arg || umove(tcp, arg, &fds) < 0) 341 continue; 342 for (j = 0; j < args[0]; j++) { 343 if (FD_ISSET(j, &fds)) { 344 if (first) { 345 sprintf(str, "%s%s [%u", sep, 346 i == 0 ? "in" : 347 i == 1 ? "out" : 348 "except", j); 349 first = 0; 350 sep = ", "; 351 } 352 else 353 sprintf(str, " %u", j); 354 cumlen += strlen(str); 355 if (cumlen < sizeof(outstr)) 356 strcat(outstr, str); 357 nfds--; 358 } 359 } 360 if (cumlen) 361 strcat(outstr, "]"); 362 if (nfds == 0) 363 break; 364 } 365#ifdef LINUX 366 /* This contains no useful information on SunOS. */ 367 if (args[4]) { 368 char str[20]; 369 370 if (umove(tcp, args[4], &tv) >= 0) { 371#ifdef ALPHA 372 if (bitness) { 373 tv32=(struct timeval32*)&tv; 374 sprintf(str, "%sleft {%u, %u}", sep, 375 tv32->tv_sec, tv32->tv_usec); 376 } else 377#endif 378 sprintf(str, "%sleft {%lu, %lu}", sep, 379 (long) tv.tv_sec, (long) tv.tv_usec); 380 381 if ((cumlen += strlen(str)) < sizeof(outstr)) 382 strcat(outstr, str); 383 } 384 } 385#endif /* LINUX */ 386 return RVAL_STR; 387 } 388 return 0; 389} 390 391#ifdef LINUX 392 393int 394sys_oldselect(tcp) 395struct tcb *tcp; 396{ 397 long args[5]; 398 399 if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) { 400 tprintf("[...]"); 401 return 0; 402 } 403 return decode_select(tcp, args, 0); 404} 405 406#ifdef ALPHA 407sys_osf_select(tcp) 408struct tcb *tcp; 409{ 410 long *args = tcp->u_arg; 411 return decode_select(tcp, args, 1); 412} 413#endif 414 415#endif /* LINUX */ 416 417int 418sys_select(tcp) 419struct tcb *tcp; 420{ 421 long *args = tcp->u_arg; 422 return decode_select(tcp, args, 0); 423} 424