1 /* 2 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 3 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $Id$ 29 */ 30 31 #include "defs.h" 32 #include <sys/syscall.h> 33 34 #ifdef HAVE_POLL_H 35 #include <poll.h> 36 #endif 37 #ifdef HAVE_SYS_POLL_H 38 #include <sys/poll.h> 39 #endif 40 #ifdef HAVE_STROPTS_H 41 #include <stropts.h> 42 #endif 43 #ifdef HAVE_SYS_CONF_H 44 #include <sys/conf.h> 45 #endif 46 #ifdef HAVE_SYS_STREAM_H 47 #include <sys/stream.h> 48 #endif 49 #ifdef HAVE_SYS_TIHDR_H 50 #include <sys/tihdr.h> 51 #endif 52 53 #if defined(HAVE_SYS_STREAM_H) || defined(LINUX) || defined(FREEBSD) 54 55 #ifndef HAVE_STROPTS_H 56 #define RS_HIPRI 1 57 struct strbuf { 58 int maxlen; /* no. of bytes in buffer */ 59 int len; /* no. of bytes returned */ 60 const char *buf; /* pointer to data */ 61 }; 62 #define MORECTL 1 63 #define MOREDATA 2 64 #endif /* !HAVE_STROPTS_H */ 65 66 #ifdef HAVE_SYS_TIUSER_H 67 #include <sys/tiuser.h> 68 #include <sys/sockmod.h> 69 #include <sys/timod.h> 70 #endif /* HAVE_SYS_TIUSER_H */ 71 72 #ifndef FREEBSD 73 static const struct xlat msgflags[] = { 74 { RS_HIPRI, "RS_HIPRI" }, 75 { 0, NULL }, 76 }; 77 78 79 static void 80 printstrbuf(tcp, sbp, getting) 81 struct tcb *tcp; 82 struct strbuf *sbp; 83 int getting; 84 { 85 if (sbp->maxlen == -1 && getting) 86 tprintf("{maxlen=-1}"); 87 else { 88 tprintf("{"); 89 if (getting) 90 tprintf("maxlen=%d, ", sbp->maxlen); 91 tprintf("len=%d, buf=", sbp->len); 92 printstr(tcp, (unsigned long) sbp->buf, sbp->len); 93 tprintf("}"); 94 } 95 } 96 97 static void 98 printstrbufarg(tcp, arg, getting) 99 struct tcb *tcp; 100 int arg; 101 int getting; 102 { 103 struct strbuf buf; 104 105 if (arg == 0) 106 tprintf("NULL"); 107 else if (umove(tcp, arg, &buf) < 0) 108 tprintf("{...}"); 109 else 110 printstrbuf(tcp, &buf, getting); 111 tprintf(", "); 112 } 113 114 int 115 sys_putmsg(tcp) 116 struct tcb *tcp; 117 { 118 int i; 119 120 if (entering(tcp)) { 121 /* fd */ 122 tprintf("%ld, ", tcp->u_arg[0]); 123 /* control and data */ 124 for (i = 1; i < 3; i++) 125 printstrbufarg(tcp, tcp->u_arg[i], 0); 126 /* flags */ 127 printflags(msgflags, tcp->u_arg[3], "RS_???"); 128 } 129 return 0; 130 } 131 132 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4) || defined(SVR4) 133 int 134 sys_getmsg(tcp) 135 struct tcb *tcp; 136 { 137 int i, flags; 138 139 if (entering(tcp)) { 140 /* fd */ 141 tprintf("%lu, ", tcp->u_arg[0]); 142 } else { 143 if (syserror(tcp)) { 144 tprintf("%#lx, %#lx, %#lx", 145 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]); 146 return 0; 147 } 148 /* control and data */ 149 for (i = 1; i < 3; i++) 150 printstrbufarg(tcp, tcp->u_arg[i], 1); 151 /* pointer to flags */ 152 if (tcp->u_arg[3] == 0) 153 tprintf("NULL"); 154 else if (umove(tcp, tcp->u_arg[3], &flags) < 0) 155 tprintf("[?]"); 156 else { 157 tprintf("["); 158 printflags(msgflags, flags, "RS_???"); 159 tprintf("]"); 160 } 161 /* decode return value */ 162 switch (tcp->u_rval) { 163 case MORECTL: 164 tcp->auxstr = "MORECTL"; 165 break; 166 case MORECTL|MOREDATA: 167 tcp->auxstr = "MORECTL|MOREDATA"; 168 break; 169 case MOREDATA: 170 tcp->auxstr = "MORECTL"; 171 break; 172 default: 173 tcp->auxstr = NULL; 174 break; 175 } 176 } 177 return RVAL_HEX | RVAL_STR; 178 } 179 #endif /* SPARC || SPARC64 || SUNOS4 || SVR4 */ 180 181 #if defined SYS_putpmsg || defined SYS_getpmsg 182 static const struct xlat pmsgflags[] = { 183 #ifdef MSG_HIPRI 184 { MSG_HIPRI, "MSG_HIPRI" }, 185 #endif 186 #ifdef MSG_AND 187 { MSG_ANY, "MSG_ANY" }, 188 #endif 189 #ifdef MSG_BAND 190 { MSG_BAND, "MSG_BAND" }, 191 #endif 192 { 0, NULL }, 193 }; 194 #endif 195 196 #ifdef SYS_putpmsg 197 int 198 sys_putpmsg(tcp) 199 struct tcb *tcp; 200 { 201 int i; 202 203 if (entering(tcp)) { 204 /* fd */ 205 tprintf("%ld, ", tcp->u_arg[0]); 206 /* control and data */ 207 for (i = 1; i < 3; i++) 208 printstrbufarg(tcp, tcp->u_arg[i], 0); 209 /* band */ 210 tprintf("%ld, ", tcp->u_arg[3]); 211 /* flags */ 212 printflags(pmsgflags, tcp->u_arg[4], "MSG_???"); 213 } 214 return 0; 215 } 216 #endif /* SYS_putpmsg */ 217 218 #ifdef SYS_getpmsg 219 int 220 sys_getpmsg(tcp) 221 struct tcb *tcp; 222 { 223 int i, flags; 224 225 if (entering(tcp)) { 226 /* fd */ 227 tprintf("%lu, ", tcp->u_arg[0]); 228 } else { 229 if (syserror(tcp)) { 230 tprintf("%#lx, %#lx, %#lx, %#lx", tcp->u_arg[1], 231 tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[4]); 232 return 0; 233 } 234 /* control and data */ 235 for (i = 1; i < 3; i++) 236 printstrbufarg(tcp, tcp->u_arg[i], 1); 237 /* pointer to band */ 238 printnum(tcp, tcp->u_arg[3], "%d"); 239 tprintf(", "); 240 /* pointer to flags */ 241 if (tcp->u_arg[4] == 0) 242 tprintf("NULL"); 243 else if (umove(tcp, tcp->u_arg[4], &flags) < 0) 244 tprintf("[?]"); 245 else { 246 tprintf("["); 247 printflags(pmsgflags, flags, "MSG_???"); 248 tprintf("]"); 249 } 250 /* decode return value */ 251 switch (tcp->u_rval) { 252 case MORECTL: 253 tcp->auxstr = "MORECTL"; 254 break; 255 case MORECTL|MOREDATA: 256 tcp->auxstr = "MORECTL|MOREDATA"; 257 break; 258 case MOREDATA: 259 tcp->auxstr = "MORECTL"; 260 break; 261 default: 262 tcp->auxstr = NULL; 263 break; 264 } 265 } 266 return RVAL_HEX | RVAL_STR; 267 } 268 #endif /* SYS_getpmsg */ 269 270 #endif /* !FREEBSD */ 271 272 273 #ifdef HAVE_SYS_POLL_H 274 275 static const struct xlat pollflags[] = { 276 #ifdef POLLIN 277 { POLLIN, "POLLIN" }, 278 { POLLPRI, "POLLPRI" }, 279 { POLLOUT, "POLLOUT" }, 280 #ifdef POLLRDNORM 281 { POLLRDNORM, "POLLRDNORM" }, 282 #endif 283 #ifdef POLLWRNORM 284 { POLLWRNORM, "POLLWRNORM" }, 285 #endif 286 #ifdef POLLRDBAND 287 { POLLRDBAND, "POLLRDBAND" }, 288 #endif 289 #ifdef POLLWRBAND 290 { POLLWRBAND, "POLLWRBAND" }, 291 #endif 292 { POLLERR, "POLLERR" }, 293 { POLLHUP, "POLLHUP" }, 294 { POLLNVAL, "POLLNVAL" }, 295 #endif 296 { 0, NULL }, 297 }; 298 299 static int 300 decode_poll(struct tcb *tcp, long pts) 301 { 302 struct pollfd fds; 303 unsigned nfds; 304 unsigned long size, start, cur, end, abbrev_end; 305 int failed = 0; 306 307 if (entering(tcp)) { 308 nfds = tcp->u_arg[1]; 309 size = sizeof(fds) * nfds; 310 start = tcp->u_arg[0]; 311 end = start + size; 312 if (nfds == 0 || size / sizeof(fds) != nfds || end < start) { 313 tprintf("%#lx, %d, ", 314 tcp->u_arg[0], nfds); 315 return 0; 316 } 317 if (abbrev(tcp)) { 318 abbrev_end = start + max_strlen * sizeof(fds); 319 if (abbrev_end < start) 320 abbrev_end = end; 321 } else { 322 abbrev_end = end; 323 } 324 tprintf("["); 325 for (cur = start; cur < end; cur += sizeof(fds)) { 326 if (cur > start) 327 tprintf(", "); 328 if (cur >= abbrev_end) { 329 tprintf("..."); 330 break; 331 } 332 if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) { 333 tprintf("?"); 334 failed = 1; 335 break; 336 } 337 if (fds.fd < 0) { 338 tprintf("{fd=%d}", fds.fd); 339 continue; 340 } 341 tprintf("{fd="); 342 printfd(tcp, fds.fd); 343 tprintf(", events="); 344 printflags(pollflags, fds.events, "POLL???"); 345 tprintf("}"); 346 } 347 tprintf("]"); 348 if (failed) 349 tprintf(" %#lx", start); 350 tprintf(", %d, ", nfds); 351 return 0; 352 } else { 353 static char outstr[1024]; 354 char str[64]; 355 const char *flagstr; 356 unsigned int cumlen; 357 358 if (syserror(tcp)) 359 return 0; 360 if (tcp->u_rval == 0) { 361 tcp->auxstr = "Timeout"; 362 return RVAL_STR; 363 } 364 365 nfds = tcp->u_arg[1]; 366 size = sizeof(fds) * nfds; 367 start = tcp->u_arg[0]; 368 end = start + size; 369 if (nfds == 0 || size / sizeof(fds) != nfds || end < start) 370 return 0; 371 if (abbrev(tcp)) { 372 abbrev_end = start + max_strlen * sizeof(fds); 373 if (abbrev_end < start) 374 abbrev_end = end; 375 } else { 376 abbrev_end = end; 377 } 378 379 outstr[0] = '\0'; 380 cumlen = 0; 381 382 for (cur = start; cur < end; cur += sizeof(fds)) { 383 if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) { 384 ++cumlen; 385 if (cumlen < sizeof(outstr)) 386 strcat(outstr, "?"); 387 failed = 1; 388 break; 389 } 390 if (!fds.revents) 391 continue; 392 if (!cumlen) { 393 ++cumlen; 394 strcat(outstr, "["); 395 } else { 396 cumlen += 2; 397 if (cumlen < sizeof(outstr)) 398 strcat(outstr, ", "); 399 } 400 if (cur >= abbrev_end) { 401 cumlen += 3; 402 if (cumlen < sizeof(outstr)) 403 strcat(outstr, "..."); 404 break; 405 } 406 sprintf(str, "{fd=%d, revents=", fds.fd); 407 flagstr=sprintflags("", pollflags, fds.revents); 408 cumlen += strlen(str) + strlen(flagstr) + 1; 409 if (cumlen < sizeof(outstr)) { 410 strcat(outstr, str); 411 strcat(outstr, flagstr); 412 strcat(outstr, "}"); 413 } 414 } 415 if (failed) 416 return 0; 417 418 if (cumlen && ++cumlen < sizeof(outstr)) 419 strcat(outstr, "]"); 420 421 if (pts) { 422 char str[128]; 423 424 sprintf(str, "%sleft ", cumlen ? ", " : ""); 425 sprint_timespec(str + strlen(str), tcp, pts); 426 if ((cumlen += strlen(str)) < sizeof(outstr)) 427 strcat(outstr, str); 428 } 429 430 if (!outstr[0]) 431 return 0; 432 433 tcp->auxstr = outstr; 434 return RVAL_STR; 435 } 436 } 437 438 int 439 sys_poll(struct tcb *tcp) 440 { 441 int rc = decode_poll(tcp, 0); 442 if (entering(tcp)) { 443 #ifdef INFTIM 444 if (tcp->u_arg[2] == INFTIM) 445 tprintf("INFTIM"); 446 else 447 #endif 448 tprintf("%ld", tcp->u_arg[2]); 449 } 450 return rc; 451 } 452 453 #ifdef LINUX 454 int 455 sys_ppoll(struct tcb *tcp) 456 { 457 int rc = decode_poll(tcp, tcp->u_arg[2]); 458 if (entering(tcp)) { 459 print_timespec(tcp, tcp->u_arg[2]); 460 tprintf(", "); 461 print_sigset(tcp, tcp->u_arg[3], 0); 462 tprintf(", %lu", tcp->u_arg[4]); 463 } 464 return rc; 465 } 466 #endif 467 468 #else /* !HAVE_SYS_POLL_H */ 469 int 470 sys_poll(tcp) 471 struct tcb *tcp; 472 { 473 return 0; 474 } 475 #endif 476 477 #if !defined(LINUX) && !defined(FREEBSD) 478 479 static const struct xlat stream_flush_options[] = { 480 { FLUSHR, "FLUSHR" }, 481 { FLUSHW, "FLUSHW" }, 482 { FLUSHRW, "FLUSHRW" }, 483 #ifdef FLUSHBAND 484 { FLUSHBAND, "FLUSHBAND" }, 485 #endif 486 { 0, NULL }, 487 }; 488 489 static const struct xlat stream_setsig_flags[] = { 490 { S_INPUT, "S_INPUT" }, 491 { S_HIPRI, "S_HIPRI" }, 492 { S_OUTPUT, "S_OUTPUT" }, 493 { S_MSG, "S_MSG" }, 494 #ifdef S_ERROR 495 { S_ERROR, "S_ERROR" }, 496 #endif 497 #ifdef S_HANGUP 498 { S_HANGUP, "S_HANGUP" }, 499 #endif 500 #ifdef S_RDNORM 501 { S_RDNORM, "S_RDNORM" }, 502 #endif 503 #ifdef S_WRNORM 504 { S_WRNORM, "S_WRNORM" }, 505 #endif 506 #ifdef S_RDBAND 507 { S_RDBAND, "S_RDBAND" }, 508 #endif 509 #ifdef S_WRBAND 510 { S_WRBAND, "S_WRBAND" }, 511 #endif 512 #ifdef S_BANDURG 513 { S_BANDURG, "S_BANDURG" }, 514 #endif 515 { 0, NULL }, 516 }; 517 518 static const struct xlat stream_read_options[] = { 519 { RNORM, "RNORM" }, 520 { RMSGD, "RMSGD" }, 521 { RMSGN, "RMSGN" }, 522 { 0, NULL }, 523 }; 524 525 static const struct xlat stream_read_flags[] = { 526 #ifdef RPROTDAT 527 { RPROTDAT, "RPROTDAT" }, 528 #endif 529 #ifdef RPROTDIS 530 { RPROTDIS, "RPROTDIS" }, 531 #endif 532 #ifdef RPROTNORM 533 { RPROTNORM, "RPROTNORM" }, 534 #endif 535 { 0, NULL }, 536 }; 537 538 #ifndef RMODEMASK 539 #define RMODEMASK (~0) 540 #endif 541 542 #ifdef I_SWROPT 543 static const struct xlat stream_write_flags[] = { 544 { SNDZERO, "SNDZERO" }, 545 { SNDPIPE, "SNDPIPE" }, 546 { 0, NULL }, 547 }; 548 #endif /* I_SWROPT */ 549 550 #ifdef I_ATMARK 551 static const struct xlat stream_atmark_options[] = { 552 { ANYMARK, "ANYMARK" }, 553 { LASTMARK, "LASTMARK" }, 554 { 0, NULL }, 555 }; 556 #endif /* I_ATMARK */ 557 558 #ifdef TI_BIND 559 static const struct xlat transport_user_options[] = { 560 { T_CONN_REQ, "T_CONN_REQ" }, 561 { T_CONN_RES, "T_CONN_RES" }, 562 { T_DISCON_REQ, "T_DISCON_REQ" }, 563 { T_DATA_REQ, "T_DATA_REQ" }, 564 { T_EXDATA_REQ, "T_EXDATA_REQ" }, 565 { T_INFO_REQ, "T_INFO_REQ" }, 566 { T_BIND_REQ, "T_BIND_REQ" }, 567 { T_UNBIND_REQ, "T_UNBIND_REQ" }, 568 { T_UNITDATA_REQ,"T_UNITDATA_REQ"}, 569 { T_OPTMGMT_REQ,"T_OPTMGMT_REQ" }, 570 { T_ORDREL_REQ, "T_ORDREL_REQ" }, 571 { 0, NULL }, 572 }; 573 574 static const struct xlat transport_user_flags [] = { 575 { 0, "0" }, 576 { T_MORE, "T_MORE" }, 577 { T_EXPEDITED, "T_EXPEDITED" }, 578 { T_NEGOTIATE, "T_NEGOTIATE" }, 579 { T_CHECK, "T_CHECK" }, 580 { T_DEFAULT, "T_DEFAULT" }, 581 { T_SUCCESS, "T_SUCCESS" }, 582 { T_FAILURE, "T_FAILURE" }, 583 { T_CURRENT, "T_CURRENT" }, 584 { T_PARTSUCCESS,"T_PARTSUCCESS" }, 585 { T_READONLY, "T_READONLY" }, 586 { T_NOTSUPPORT, "T_NOTSUPPORT" }, 587 { 0, NULL }, 588 }; 589 590 591 #ifdef HAVE_STRUCT_T_OPTHDR 592 593 static const struct xlat xti_level [] = { 594 { XTI_GENERIC, "XTI_GENERIC" }, 595 { 0, NULL }, 596 }; 597 598 static const struct xlat xti_generic [] = { 599 { XTI_DEBUG, "XTI_DEBUG" }, 600 { XTI_LINGER, "XTI_LINGER" }, 601 { XTI_RCVBUF, "XTI_RCVBUF" }, 602 { XTI_RCVLOWAT, "XTI_RCVLOWAT" }, 603 { XTI_SNDBUF, "XTI_SNDBUF" }, 604 { XTI_SNDLOWAT, "XTI_SNDLOWAT" }, 605 { 0, NULL }, 606 }; 607 608 609 610 void 611 print_xti_optmgmt (tcp, addr, len) 612 struct tcb *tcp; 613 long addr; 614 int len; 615 { 616 int c = 0; 617 struct t_opthdr hdr; 618 619 while (len >= (int) sizeof hdr) { 620 if (umove(tcp, addr, &hdr) < 0) break; 621 if (c++) { 622 tprintf (", "); 623 } 624 else if (len > hdr.len + sizeof hdr) { 625 tprintf ("["); 626 } 627 tprintf ("{level="); 628 printxval (xti_level, hdr.level, "???"); 629 tprintf (", name="); 630 switch (hdr.level) { 631 case XTI_GENERIC: 632 printxval (xti_generic, hdr.name, "XTI_???"); 633 break; 634 default: 635 tprintf ("%ld", hdr.name); 636 break; 637 } 638 tprintf (", status="); 639 printxval (transport_user_flags, hdr.status, "T_???"); 640 addr += sizeof hdr; 641 len -= sizeof hdr; 642 if ((hdr.len -= sizeof hdr) > 0) { 643 if (hdr.len > len) break; 644 tprintf (", val="); 645 if (len == sizeof (int)) 646 printnum (tcp, addr, "%d"); 647 else 648 printstr (tcp, addr, hdr.len); 649 addr += hdr.len; 650 len -= hdr.len; 651 } 652 tprintf ("}"); 653 } 654 if (len > 0) { 655 if (c++) tprintf (", "); 656 printstr (tcp, addr, len); 657 } 658 if (c > 1) tprintf ("]"); 659 } 660 661 #endif 662 663 664 static void 665 print_optmgmt (tcp, addr, len) 666 struct tcb *tcp; 667 long addr; 668 int len; 669 { 670 /* We don't know how to tell if TLI (socket) or XTI 671 optmgmt is being used yet, assume TLI. */ 672 #if defined (HAVE_STRUCT_OPTHDR) 673 print_sock_optmgmt (tcp, addr, len); 674 #elif defined (HAVE_STRUCT_T_OPTHDR) 675 print_xti_optmgmt (tcp, addr, len); 676 #else 677 printstr (tcp, addr, len); 678 #endif 679 } 680 681 682 683 684 static const struct xlat service_type [] = { 685 { T_COTS, "T_COTS" }, 686 { T_COTS_ORD, "T_COTS_ORD" }, 687 { T_CLTS, "T_CLTS" }, 688 { 0, NULL }, 689 }; 690 691 static const struct xlat ts_state [] = { 692 { TS_UNBND, "TS_UNBND" }, 693 { TS_WACK_BREQ, "TS_WACK_BREQ" }, 694 { TS_WACK_UREQ, "TS_WACK_UREQ" }, 695 { TS_IDLE, "TS_IDLE" }, 696 { TS_WACK_OPTREQ,"TS_WACK_OPTREQ"}, 697 { TS_WACK_CREQ, "TS_WACK_CREQ" }, 698 { TS_WCON_CREQ, "TS_WCON_CREQ" }, 699 { TS_WRES_CIND, "TS_WRES_CIND" }, 700 { TS_WACK_CRES, "TS_WACK_CRES" }, 701 { TS_DATA_XFER, "TS_DATA_XFER" }, 702 { TS_WIND_ORDREL,"TS_WIND_ORDREL"}, 703 { TS_WREQ_ORDREL,"TS_WREQ_ORDREL"}, 704 { TS_WACK_DREQ6,"TS_WACK_DREQ6" }, 705 { TS_WACK_DREQ7,"TS_WACK_DREQ7" }, 706 { TS_WACK_DREQ9,"TS_WACK_DREQ9" }, 707 { TS_WACK_DREQ10,"TS_WACK_DREQ10"}, 708 { TS_WACK_DREQ11,"TS_WACK_DREQ11"}, 709 { 0, NULL }, 710 }; 711 712 static const struct xlat provider_flags [] = { 713 { 0, "0" }, 714 { SENDZERO, "SENDZERO" }, 715 { EXPINLINE, "EXPINLINE" }, 716 { XPG4_1, "XPG4_1" }, 717 { 0, NULL }, 718 }; 719 720 721 static const struct xlat tli_errors [] = { 722 { TBADADDR, "TBADADDR" }, 723 { TBADOPT, "TBADOPT" }, 724 { TACCES, "TACCES" }, 725 { TBADF, "TBADF" }, 726 { TNOADDR, "TNOADDR" }, 727 { TOUTSTATE, "TOUTSTATE" }, 728 { TBADSEQ, "TBADSEQ" }, 729 { TSYSERR, "TSYSERR" }, 730 { TLOOK, "TLOOK" }, 731 { TBADDATA, "TBADDATA" }, 732 { TBUFOVFLW, "TBUFOVFLW" }, 733 { TFLOW, "TFLOW" }, 734 { TNODATA, "TNODATA" }, 735 { TNODIS, "TNODIS" }, 736 { TNOUDERR, "TNOUDERR" }, 737 { TBADFLAG, "TBADFLAG" }, 738 { TNOREL, "TNOREL" }, 739 { TNOTSUPPORT, "TNOTSUPPORT" }, 740 { TSTATECHNG, "TSTATECHNG" }, 741 { TNOSTRUCTYPE, "TNOSTRUCTYPE" }, 742 { TBADNAME, "TBADNAME" }, 743 { TBADQLEN, "TBADQLEN" }, 744 { TADDRBUSY, "TADDRBUSY" }, 745 { TINDOUT, "TINDOUT" }, 746 { TPROVMISMATCH,"TPROVMISMATCH" }, 747 { TRESQLEN, "TRESQLEN" }, 748 { TRESADDR, "TRESADDR" }, 749 { TQFULL, "TQFULL" }, 750 { TPROTO, "TPROTO" }, 751 { 0, NULL }, 752 }; 753 754 755 static int 756 print_transport_message (tcp, expect, addr, len) 757 struct tcb *tcp; 758 int expect; 759 long addr; 760 int len; 761 { 762 union T_primitives m; 763 int c = 0; 764 765 if (len < sizeof m.type) goto dump; 766 767 if (umove (tcp, addr, &m.type) < 0) goto dump; 768 769 #define GET(type, struct) \ 770 do { \ 771 if (len < sizeof m.struct) goto dump; \ 772 if (umove (tcp, addr, &m.struct) < 0) goto dump;\ 773 tprintf ("{"); \ 774 if (expect != type) { \ 775 ++c; \ 776 tprintf (#type); \ 777 } \ 778 } \ 779 while (0) 780 781 #define COMMA() \ 782 do { if (c++) tprintf (", "); } while (0) 783 784 785 #define STRUCT(struct, elem, print) \ 786 do { \ 787 COMMA (); \ 788 if (m.struct.elem##_length < 0 || \ 789 m.struct.elem##_offset < sizeof m.struct || \ 790 m.struct.elem##_offset + m.struct.elem##_length > len) \ 791 { \ 792 tprintf (#elem "_length=%ld, " #elem "_offset=%ld",\ 793 m.struct.elem##_length, \ 794 m.struct.elem##_offset); \ 795 } \ 796 else { \ 797 tprintf (#elem "="); \ 798 print (tcp, \ 799 addr + m.struct.elem##_offset, \ 800 m.struct.elem##_length); \ 801 } \ 802 } \ 803 while (0) 804 805 #define ADDR(struct, elem) STRUCT (struct, elem, printstr) 806 807 switch (m.type) { 808 #ifdef T_CONN_REQ 809 case T_CONN_REQ: /* connect request */ 810 GET (T_CONN_REQ, conn_req); 811 ADDR (conn_req, DEST); 812 ADDR (conn_req, OPT); 813 break; 814 #endif 815 #ifdef T_CONN_RES 816 case T_CONN_RES: /* connect response */ 817 GET (T_CONN_RES, conn_res); 818 #ifdef HAVE_STRUCT_T_CONN_RES_QUEUE_PTR 819 COMMA (); 820 tprintf ("QUEUE=%p", m.conn_res.QUEUE_ptr); 821 #elif defined HAVE_STRUCT_T_CONN_RES_ACCEPTOR_ID 822 COMMA (); 823 tprintf ("ACCEPTOR=%#lx", m.conn_res.ACCEPTOR_id); 824 #endif 825 ADDR (conn_res, OPT); 826 COMMA (); 827 tprintf ("SEQ=%ld", m.conn_res.SEQ_number); 828 break; 829 #endif 830 #ifdef T_DISCON_REQ 831 case T_DISCON_REQ: /* disconnect request */ 832 GET (T_DISCON_REQ, discon_req); 833 COMMA (); 834 tprintf ("SEQ=%ld", m.discon_req.SEQ_number); 835 break; 836 #endif 837 #ifdef T_DATA_REQ 838 case T_DATA_REQ: /* data request */ 839 GET (T_DATA_REQ, data_req); 840 COMMA (); 841 tprintf ("MORE=%ld", m.data_req.MORE_flag); 842 break; 843 #endif 844 #ifdef T_EXDATA_REQ 845 case T_EXDATA_REQ: /* expedited data req */ 846 GET (T_EXDATA_REQ, exdata_req); 847 COMMA (); 848 tprintf ("MORE=%ld", m.exdata_req.MORE_flag); 849 break; 850 #endif 851 #ifdef T_INFO_REQ 852 case T_INFO_REQ: /* information req */ 853 GET (T_INFO_REQ, info_req); 854 break; 855 #endif 856 #ifdef T_BIND_REQ 857 case T_BIND_REQ: /* bind request */ 858 #ifdef O_T_BIND_REQ 859 case O_T_BIND_REQ: /* Ugly xti/tli hack */ 860 #endif 861 GET (T_BIND_REQ, bind_req); 862 ADDR (bind_req, ADDR); 863 COMMA (); 864 tprintf ("CONIND=%ld", m.bind_req.CONIND_number); 865 break; 866 #endif 867 #ifdef T_UNBIND_REQ 868 case T_UNBIND_REQ: /* unbind request */ 869 GET (T_UNBIND_REQ, unbind_req); 870 break; 871 #endif 872 #ifdef T_UNITDATA_REQ 873 case T_UNITDATA_REQ: /* unitdata requset */ 874 GET (T_UNITDATA_REQ, unitdata_req); 875 ADDR (unitdata_req, DEST); 876 ADDR (unitdata_req, OPT); 877 break; 878 #endif 879 #ifdef T_OPTMGMT_REQ 880 case T_OPTMGMT_REQ: /* manage opt req */ 881 GET (T_OPTMGMT_REQ, optmgmt_req); 882 COMMA (); 883 tprintf ("MGMT="); 884 printflags (transport_user_flags, m.optmgmt_req.MGMT_flags, 885 "T_???"); 886 STRUCT (optmgmt_req, OPT, print_optmgmt); 887 break; 888 #endif 889 #ifdef T_ORDREL_REQ 890 case T_ORDREL_REQ: /* orderly rel req */ 891 GET (T_ORDREL_REQ, ordrel_req); 892 break; 893 #endif 894 #ifdef T_CONN_IND 895 case T_CONN_IND: /* connect indication */ 896 GET (T_CONN_IND, conn_ind); 897 ADDR (conn_ind, SRC); 898 ADDR (conn_ind, OPT); 899 tprintf (", SEQ=%ld", m.conn_ind.SEQ_number); 900 break; 901 #endif 902 #ifdef T_CONN_CON 903 case T_CONN_CON: /* connect corfirm */ 904 GET (T_CONN_CON, conn_con); 905 ADDR (conn_con, RES); 906 ADDR (conn_con, OPT); 907 break; 908 #endif 909 #ifdef T_DISCON_IND 910 case T_DISCON_IND: /* discon indication */ 911 GET (T_DISCON_IND, discon_ind); 912 COMMA (); 913 tprintf ("DISCON=%ld, SEQ=%ld", 914 m.discon_ind.DISCON_reason, m.discon_ind.SEQ_number); 915 break; 916 #endif 917 #ifdef T_DATA_IND 918 case T_DATA_IND: /* data indication */ 919 GET (T_DATA_IND, data_ind); 920 COMMA (); 921 tprintf ("MORE=%ld", m.data_ind.MORE_flag); 922 break; 923 #endif 924 #ifdef T_EXDATA_IND 925 case T_EXDATA_IND: /* expedited data ind */ 926 GET (T_EXDATA_IND, exdata_ind); 927 COMMA (); 928 tprintf ("MORE=%ld", m.exdata_ind.MORE_flag); 929 break; 930 #endif 931 #ifdef T_INFO_ACK 932 case T_INFO_ACK: /* info ack */ 933 GET (T_INFO_ACK, info_ack); 934 COMMA (); 935 tprintf ("TSDU=%ld, ETSDU=%ld, CDATA=%ld, DDATA=%ld, " 936 "ADDR=%ld, OPT=%ld, TIDU=%ld, SERV=", 937 m.info_ack.TSDU_size, m.info_ack.ETSDU_size, 938 m.info_ack.CDATA_size, m.info_ack.DDATA_size, 939 m.info_ack.ADDR_size, m.info_ack.OPT_size, 940 m.info_ack.TIDU_size); 941 printxval (service_type, m.info_ack.SERV_type, "T_???"); 942 tprintf (", CURRENT="); 943 printxval (ts_state, m.info_ack.CURRENT_state, "TS_???"); 944 tprintf (", PROVIDER="); 945 printflags (provider_flags, m.info_ack.PROVIDER_flag, "???"); 946 break; 947 #endif 948 #ifdef T_BIND_ACK 949 case T_BIND_ACK: /* bind ack */ 950 GET (T_BIND_ACK, bind_ack); 951 ADDR (bind_ack, ADDR); 952 tprintf (", CONIND=%ld", m.bind_ack.CONIND_number); 953 break; 954 #endif 955 #ifdef T_ERROR_ACK 956 case T_ERROR_ACK: /* error ack */ 957 GET (T_ERROR_ACK, error_ack); 958 COMMA (); 959 tprintf ("ERROR="); 960 printxval (transport_user_options, 961 m.error_ack.ERROR_prim, "TI_???"); 962 tprintf (", TLI="); 963 printxval (tli_errors, m.error_ack.TLI_error, "T???"); 964 tprintf ("UNIX=%s", strerror (m.error_ack.UNIX_error)); 965 break; 966 #endif 967 #ifdef T_OK_ACK 968 case T_OK_ACK: /* ok ack */ 969 GET (T_OK_ACK, ok_ack); 970 COMMA (); 971 tprintf ("CORRECT="); 972 printxval (transport_user_options, 973 m.ok_ack.CORRECT_prim, "TI_???"); 974 break; 975 #endif 976 #ifdef T_UNITDATA_IND 977 case T_UNITDATA_IND: /* unitdata ind */ 978 GET (T_UNITDATA_IND, unitdata_ind); 979 ADDR (unitdata_ind, SRC); 980 ADDR (unitdata_ind, OPT); 981 break; 982 #endif 983 #ifdef T_UDERROR_IND 984 case T_UDERROR_IND: /* unitdata error ind */ 985 GET (T_UDERROR_IND, uderror_ind); 986 ADDR (uderror_ind, DEST); 987 ADDR (uderror_ind, OPT); 988 tprintf (", ERROR=%ld", m.uderror_ind.ERROR_type); 989 break; 990 #endif 991 #ifdef T_OPTMGMT_ACK 992 case T_OPTMGMT_ACK: /* manage opt ack */ 993 GET (T_OPTMGMT_ACK, optmgmt_ack); 994 COMMA (); 995 tprintf ("MGMT="); 996 printflags (transport_user_flags, m.optmgmt_ack.MGMT_flags, 997 "T_???"); 998 STRUCT (optmgmt_ack, OPT, print_optmgmt); 999 break; 1000 #endif 1001 #ifdef T_ORDREL_IND 1002 case T_ORDREL_IND: /* orderly rel ind */ 1003 GET (T_ORDREL_IND, ordrel_ind); 1004 break; 1005 #endif 1006 #ifdef T_ADDR_REQ 1007 case T_ADDR_REQ: /* address req */ 1008 GET (T_ADDR_REQ, addr_req); 1009 break; 1010 #endif 1011 #ifdef T_ADDR_ACK 1012 case T_ADDR_ACK: /* address response */ 1013 GET (T_ADDR_ACK, addr_ack); 1014 ADDR (addr_ack, LOCADDR); 1015 ADDR (addr_ack, REMADDR); 1016 break; 1017 #endif 1018 default: 1019 dump: 1020 c = -1; 1021 printstr(tcp, addr, len); 1022 break; 1023 } 1024 1025 if (c >= 0) tprintf ("}"); 1026 1027 #undef ADDR 1028 #undef COMMA 1029 #undef STRUCT 1030 1031 return 0; 1032 } 1033 1034 1035 #endif /* TI_BIND */ 1036 1037 1038 static int internal_stream_ioctl(struct tcb *tcp, int arg) 1039 { 1040 struct strioctl si; 1041 struct ioctlent *iop; 1042 int in_and_out; 1043 int timod = 0; 1044 #ifdef SI_GETUDATA 1045 struct si_udata udata; 1046 #endif /* SI_GETUDATA */ 1047 1048 if (!arg) 1049 return 0; 1050 if (umove(tcp, arg, &si) < 0) { 1051 if (entering(tcp)) 1052 tprintf(", {...}"); 1053 return 1; 1054 } 1055 if (entering(tcp)) { 1056 iop = ioctl_lookup(si.ic_cmd); 1057 if (iop) { 1058 tprintf(", {ic_cmd=%s", iop->symbol); 1059 while ((iop = ioctl_next_match(iop))) 1060 tprintf(" or %s", iop->symbol); 1061 } else 1062 tprintf(", {ic_cmd=%#x", si.ic_cmd); 1063 if (si.ic_timout == INFTIM) 1064 tprintf(", ic_timout=INFTIM, "); 1065 else 1066 tprintf(" ic_timout=%d, ", si.ic_timout); 1067 } 1068 in_and_out = 1; 1069 switch (si.ic_cmd) { 1070 #ifdef SI_GETUDATA 1071 case SI_GETUDATA: 1072 in_and_out = 0; 1073 break; 1074 #endif /* SI_GETUDATA */ 1075 } 1076 if (in_and_out) { 1077 if (entering(tcp)) 1078 tprintf("/* in */ "); 1079 else 1080 tprintf(", /* out */ "); 1081 } 1082 if (in_and_out || entering(tcp)) 1083 tprintf("ic_len=%d, ic_dp=", si.ic_len); 1084 switch (si.ic_cmd) { 1085 #ifdef TI_BIND 1086 case TI_BIND: 1087 /* in T_BIND_REQ, out T_BIND_ACK */ 1088 ++timod; 1089 if (entering(tcp)) { 1090 print_transport_message (tcp, 1091 T_BIND_REQ, 1092 si.ic_dp, si.ic_len); 1093 } 1094 else { 1095 print_transport_message (tcp, 1096 T_BIND_ACK, 1097 si.ic_dp, si.ic_len); 1098 } 1099 break; 1100 #endif /* TI_BIND */ 1101 #ifdef TI_UNBIND 1102 case TI_UNBIND: 1103 /* in T_UNBIND_REQ, out T_OK_ACK */ 1104 ++timod; 1105 if (entering(tcp)) { 1106 print_transport_message (tcp, 1107 T_UNBIND_REQ, 1108 si.ic_dp, si.ic_len); 1109 } 1110 else { 1111 print_transport_message (tcp, 1112 T_OK_ACK, 1113 si.ic_dp, si.ic_len); 1114 } 1115 break; 1116 #endif /* TI_UNBIND */ 1117 #ifdef TI_GETINFO 1118 case TI_GETINFO: 1119 /* in T_INFO_REQ, out T_INFO_ACK */ 1120 ++timod; 1121 if (entering(tcp)) { 1122 print_transport_message (tcp, 1123 T_INFO_REQ, 1124 si.ic_dp, si.ic_len); 1125 } 1126 else { 1127 print_transport_message (tcp, 1128 T_INFO_ACK, 1129 si.ic_dp, si.ic_len); 1130 } 1131 break; 1132 #endif /* TI_GETINFO */ 1133 #ifdef TI_OPTMGMT 1134 case TI_OPTMGMT: 1135 /* in T_OPTMGMT_REQ, out T_OPTMGMT_ACK */ 1136 ++timod; 1137 if (entering(tcp)) { 1138 print_transport_message (tcp, 1139 T_OPTMGMT_REQ, 1140 si.ic_dp, si.ic_len); 1141 } 1142 else { 1143 print_transport_message (tcp, 1144 T_OPTMGMT_ACK, 1145 si.ic_dp, si.ic_len); 1146 } 1147 break; 1148 #endif /* TI_OPTMGMT */ 1149 #ifdef SI_GETUDATA 1150 case SI_GETUDATA: 1151 if (entering(tcp)) 1152 break; 1153 if (umove(tcp, (int) si.ic_dp, &udata) < 0) 1154 tprintf("{...}"); 1155 else { 1156 tprintf("{tidusize=%d, addrsize=%d, ", 1157 udata.tidusize, udata.addrsize); 1158 tprintf("optsize=%d, etsdusize=%d, ", 1159 udata.optsize, udata.etsdusize); 1160 tprintf("servtype=%d, so_state=%d, ", 1161 udata.servtype, udata.so_state); 1162 tprintf("so_options=%d", udata.so_options); 1163 tprintf("}"); 1164 } 1165 break; 1166 #endif /* SI_GETUDATA */ 1167 default: 1168 printstr(tcp, (long) si.ic_dp, si.ic_len); 1169 break; 1170 } 1171 if (exiting(tcp)) { 1172 tprintf("}"); 1173 if (timod && tcp->u_rval && !syserror(tcp)) { 1174 tcp->auxstr = xlookup (tli_errors, tcp->u_rval); 1175 return RVAL_STR + 1; 1176 } 1177 } 1178 1179 return 1; 1180 } 1181 1182 int 1183 stream_ioctl(tcp, code, arg) 1184 struct tcb *tcp; 1185 int code, arg; 1186 { 1187 #ifdef I_LIST 1188 int i; 1189 #endif 1190 int val; 1191 #ifdef I_FLUSHBAND 1192 struct bandinfo bi; 1193 #endif 1194 struct strpeek sp; 1195 struct strfdinsert sfi; 1196 struct strrecvfd srf; 1197 #ifdef I_LIST 1198 struct str_list sl; 1199 #endif 1200 1201 /* I_STR is a special case because the data is read & written. */ 1202 if (code == I_STR) 1203 return internal_stream_ioctl(tcp, arg); 1204 if (entering(tcp)) 1205 return 0; 1206 1207 switch (code) { 1208 case I_PUSH: 1209 case I_LOOK: 1210 case I_FIND: 1211 /* arg is a string */ 1212 tprintf(", "); 1213 printpath(tcp, arg); 1214 return 1; 1215 case I_POP: 1216 /* doesn't take an argument */ 1217 return 1; 1218 case I_FLUSH: 1219 /* argument is an option */ 1220 tprintf(", "); 1221 printxval(stream_flush_options, arg, "FLUSH???"); 1222 return 1; 1223 #ifdef I_FLUSHBAND 1224 case I_FLUSHBAND: 1225 /* argument is a pointer to a bandinfo struct */ 1226 if (umove(tcp, arg, &bi) < 0) 1227 tprintf(", {...}"); 1228 else { 1229 tprintf(", {bi_pri=%d, bi_flag=", bi.bi_pri); 1230 printflags(stream_flush_options, bi.bi_flag, "FLUSH???"); 1231 tprintf("}"); 1232 } 1233 return 1; 1234 #endif /* I_FLUSHBAND */ 1235 case I_SETSIG: 1236 /* argument is a set of flags */ 1237 tprintf(", "); 1238 printflags(stream_setsig_flags, arg, "S_???"); 1239 return 1; 1240 case I_GETSIG: 1241 /* argument is a pointer to a set of flags */ 1242 if (syserror(tcp)) 1243 return 0; 1244 tprintf(", ["); 1245 if (umove(tcp, arg, &val) < 0) 1246 tprintf("?"); 1247 else 1248 printflags(stream_setsig_flags, val, "S_???"); 1249 tprintf("]"); 1250 return 1; 1251 case I_PEEK: 1252 /* argument is a pointer to a strpeek structure */ 1253 if (syserror(tcp) || !arg) 1254 return 0; 1255 if (umove(tcp, arg, &sp) < 0) { 1256 tprintf(", {...}"); 1257 return 1; 1258 } 1259 tprintf(", {ctlbuf="); 1260 printstrbuf(tcp, &sp.ctlbuf, 1); 1261 tprintf(", databuf="); 1262 printstrbuf(tcp, &sp.databuf, 1); 1263 tprintf(", flags="); 1264 printflags(msgflags, sp.flags, "RS_???"); 1265 tprintf("}"); 1266 return 1; 1267 case I_SRDOPT: 1268 /* argument is an option with flags */ 1269 tprintf(", "); 1270 printxval(stream_read_options, arg & RMODEMASK, "R???"); 1271 addflags(stream_read_flags, arg & ~RMODEMASK); 1272 return 1; 1273 case I_GRDOPT: 1274 /* argument is an pointer to an option with flags */ 1275 if (syserror(tcp)) 1276 return 0; 1277 tprintf(", ["); 1278 if (umove(tcp, arg, &val) < 0) 1279 tprintf("?"); 1280 else { 1281 printxval(stream_read_options, 1282 arg & RMODEMASK, "R???"); 1283 addflags(stream_read_flags, arg & ~RMODEMASK); 1284 } 1285 tprintf("]"); 1286 return 1; 1287 case I_NREAD: 1288 #ifdef I_GETBAND 1289 case I_GETBAND: 1290 #endif 1291 #ifdef I_SETCLTIME 1292 case I_SETCLTIME: 1293 #endif 1294 #ifdef I_GETCLTIME 1295 case I_GETCLTIME: 1296 #endif 1297 /* argument is a pointer to a decimal integer */ 1298 if (syserror(tcp)) 1299 return 0; 1300 tprintf(", "); 1301 printnum(tcp, arg, "%d"); 1302 return 1; 1303 case I_FDINSERT: 1304 /* argument is a pointer to a strfdinsert structure */ 1305 if (syserror(tcp) || !arg) 1306 return 0; 1307 if (umove(tcp, arg, &sfi) < 0) { 1308 tprintf(", {...}"); 1309 return 1; 1310 } 1311 tprintf(", {ctlbuf="); 1312 printstrbuf(tcp, &sfi.ctlbuf, 1); 1313 tprintf(", databuf="); 1314 printstrbuf(tcp, &sfi.databuf, 1); 1315 tprintf(", flags="); 1316 printflags(msgflags, sfi.flags, "RS_???"); 1317 tprintf(", filedes=%d, offset=%d}", sfi.fildes, sfi.offset); 1318 return 1; 1319 #ifdef I_SWROPT 1320 case I_SWROPT: 1321 /* argument is a set of flags */ 1322 tprintf(", "); 1323 printflags(stream_write_flags, arg, "SND???"); 1324 return 1; 1325 #endif /* I_SWROPT */ 1326 #ifdef I_GWROPT 1327 case I_GWROPT: 1328 /* argument is an pointer to an option with flags */ 1329 if (syserror(tcp)) 1330 return 0; 1331 tprintf(", ["); 1332 if (umove(tcp, arg, &val) < 0) 1333 tprintf("?"); 1334 else 1335 printflags(stream_write_flags, arg, "SND???"); 1336 tprintf("]"); 1337 return 1; 1338 #endif /* I_GWROPT */ 1339 case I_SENDFD: 1340 #ifdef I_CKBAND 1341 case I_CKBAND: 1342 #endif 1343 #ifdef I_CANPUT 1344 case I_CANPUT: 1345 #endif 1346 case I_LINK: 1347 case I_UNLINK: 1348 case I_PLINK: 1349 case I_PUNLINK: 1350 /* argument is a decimal integer */ 1351 tprintf(", %d", arg); 1352 return 1; 1353 case I_RECVFD: 1354 /* argument is a pointer to a strrecvfd structure */ 1355 if (syserror(tcp) || !arg) 1356 return 0; 1357 if (umove(tcp, arg, &srf) < 0) { 1358 tprintf(", {...}"); 1359 return 1; 1360 } 1361 tprintf(", {fd=%d, uid=%lu, gid=%lu}", srf.fd, 1362 (unsigned long) srf.uid, (unsigned long) srf.gid); 1363 return 1; 1364 #ifdef I_LIST 1365 case I_LIST: 1366 if (syserror(tcp)) 1367 return 0; 1368 if (arg == 0) { 1369 tprintf(", NULL"); 1370 return 1; 1371 } 1372 if (umove(tcp, arg, &sl) < 0) { 1373 tprintf(", {...}"); 1374 return 1; 1375 } 1376 tprintf(", {sl_nmods=%d, sl_modlist=[", sl.sl_nmods); 1377 for (i = 0; i < tcp->u_rval; i++) { 1378 if (i) 1379 tprintf(", "); 1380 printpath(tcp, (int) sl.sl_modlist[i].l_name); 1381 } 1382 tprintf("]}"); 1383 return 1; 1384 #endif /* I_LIST */ 1385 #ifdef I_ATMARK 1386 case I_ATMARK: 1387 tprintf(", "); 1388 printxval(stream_atmark_options, arg, "???MARK"); 1389 return 1; 1390 #endif /* I_ATMARK */ 1391 default: 1392 return 0; 1393 } 1394 } 1395 1396 #endif /* !LINUX && !FREEBSD */ 1397 1398 #endif /* HAVE_SYS_STREAM_H || LINUX || FREEBSD */ 1399