blob: 0ddb5f12f092e5dd864b1f1fef1923922ac2be18 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * $Id$
28 */
29
30#include "defs.h"
31
Wichert Akkermand4d8e921999-04-18 23:30:29 +000032#if defined(HAVE_SYS_STREAM_H) || defined(linux)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000033
Wichert Akkermand4d8e921999-04-18 23:30:29 +000034#if defined(linux)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000035#include <sys/poll.h>
36
37#define RS_HIPRI 1
38struct strbuf {
39 int maxlen; /* no. of bytes in buffer */
40 int len; /* no. of bytes returned */
41 char *buf; /* pointer to data */
42};
43#define MORECTL 1
44#define MOREDATA 2
45
Wichert Akkermand4d8e921999-04-18 23:30:29 +000046#else /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000047
48#include <stropts.h>
49#include <poll.h>
50#include <sys/conf.h>
51#include <sys/stream.h>
52#include <sys/tihdr.h>
53
Wichert Akkermand4d8e921999-04-18 23:30:29 +000054#endif /* linux */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000055
56#ifdef HAVE_SYS_TIUSER_H
57#include <sys/tiuser.h>
58#include <sys/sockmod.h>
59#include <sys/timod.h>
60#endif /* HAVE_SYS_TIUSER_H */
61
62static struct xlat msgflags[] = {
63 { RS_HIPRI, "RS_HIPRI" },
64 { 0, NULL },
65};
66
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000067
68static void
69printstrbuf(tcp, sbp, getting)
70struct tcb *tcp;
71struct strbuf *sbp;
72int getting;
73{
74 if (sbp->maxlen == -1 && getting)
75 tprintf("{maxlen=-1}");
76 else {
77 tprintf("{");
78 if (getting)
79 tprintf("maxlen=%d, ", sbp->maxlen);
80 tprintf("len=%d, buf=", sbp->len);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000081 printstr(tcp, (unsigned long) sbp->buf, sbp->len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000082 tprintf("}");
83 }
84}
85
86static void
87printstrbufarg(tcp, arg, getting)
88struct tcb *tcp;
89int arg;
90int getting;
91{
92 struct strbuf buf;
93
94 if (arg == 0)
95 tprintf("NULL");
96 else if (umove(tcp, arg, &buf) < 0)
97 tprintf("{...}");
98 else
99 printstrbuf(tcp, &buf, getting);
100 tprintf(", ");
101}
102
103int
104sys_putmsg(tcp)
105struct tcb *tcp;
106{
107 int i;
108
109 if (entering(tcp)) {
110 /* fd */
111 tprintf("%ld, ", tcp->u_arg[0]);
112 /* control and data */
113 for (i = 1; i < 3; i++)
114 printstrbufarg(tcp, tcp->u_arg[i], 0);
115 /* flags */
116 if (!printflags(msgflags, tcp->u_arg[3]))
117 tprintf("0");
118 }
119 return 0;
120}
121
122int
123sys_getmsg(tcp)
124struct tcb *tcp;
125{
126 int i, flags;
127
128 if (entering(tcp)) {
129 /* fd */
130 tprintf("%lu, ", tcp->u_arg[0]);
131 } else {
132 if (syserror(tcp)) {
133 tprintf("%#lx, %#lx, %#lx",
134 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
135 return 0;
136 }
137 /* control and data */
138 for (i = 1; i < 3; i++)
139 printstrbufarg(tcp, tcp->u_arg[i], 1);
140 /* pointer to flags */
141 if (tcp->u_arg[3] == 0)
142 tprintf("NULL");
143 else if (umove(tcp, tcp->u_arg[3], &flags) < 0)
144 tprintf("[?]");
145 else {
146 tprintf("[");
147 if (!printflags(msgflags, flags))
148 tprintf("0");
149 tprintf("]");
150 }
151 /* decode return value */
152 switch (tcp->u_rval) {
153 case MORECTL:
154 tcp->auxstr = "MORECTL";
155 break;
156 case MORECTL|MOREDATA:
157 tcp->auxstr = "MORECTL|MOREDATA";
158 break;
159 case MOREDATA:
160 tcp->auxstr = "MORECTL";
161 break;
162 default:
163 tcp->auxstr = NULL;
164 break;
165 }
166 }
167 return RVAL_HEX | RVAL_STR;
168}
169
170#ifdef HAVE_PUTPMSG
171
172static struct xlat pmsgflags[] = {
173 { MSG_HIPRI, "MSG_HIPRI" },
174 { MSG_ANY, "MSG_ANY" },
175 { MSG_BAND, "MSG_BAND" },
176 { 0, NULL },
177};
178
179int
180sys_putpmsg(tcp)
181struct tcb *tcp;
182{
183 int i;
184
185 if (entering(tcp)) {
186 /* fd */
187 tprintf("%ld, ", tcp->u_arg[0]);
188 /* control and data */
189 for (i = 1; i < 3; i++)
190 printstrbufarg(tcp, tcp->u_arg[i], 0);
191 /* band */
192 tprintf("%ld, ", tcp->u_arg[3]);
193 /* flags */
194 if (!printflags(pmsgflags, tcp->u_arg[4]))
195 tprintf("0");
196 }
197 return 0;
198}
199
200int
201sys_getpmsg(tcp)
202struct tcb *tcp;
203{
204 int i, flags;
205
206 if (entering(tcp)) {
207 /* fd */
208 tprintf("%lu, ", tcp->u_arg[0]);
209 } else {
210 if (syserror(tcp)) {
211 tprintf("%#lx, %#lx, %#lx, %#lx", tcp->u_arg[1],
212 tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[4]);
213 return 0;
214 }
215 /* control and data */
216 for (i = 1; i < 3; i++)
217 printstrbufarg(tcp, tcp->u_arg[i], 1);
218 /* pointer to band */
219 printnum(tcp, tcp->u_arg[3], "%d");
220 /* pointer to flags */
221 if (tcp->u_arg[4] == 0)
222 tprintf("NULL");
223 else if (umove(tcp, tcp->u_arg[4], &flags) < 0)
224 tprintf("[?]");
225 else {
226 tprintf("[");
227 if (!printflags(pmsgflags, flags))
228 tprintf("0");
229 tprintf("]");
230 }
231 /* decode return value */
232 switch (tcp->u_rval) {
233 case MORECTL:
234 tcp->auxstr = "MORECTL";
235 break;
236 case MORECTL|MOREDATA:
237 tcp->auxstr = "MORECTL|MOREDATA";
238 break;
239 case MOREDATA:
240 tcp->auxstr = "MORECTL";
241 break;
242 default:
243 tcp->auxstr = NULL;
244 break;
245 }
246 }
247 return RVAL_HEX | RVAL_STR;
248}
249
250#endif /* HAVE_PUTPMSG */
251
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000252
253static struct xlat pollflags[] = {
254 { POLLIN, "POLLIN" },
255 { POLLPRI, "POLLPRI" },
256 { POLLOUT, "POLLOUT" },
257#ifdef POLLRDNORM
258 { POLLRDNORM, "POLLRDNORM" },
259#endif
260#ifdef POLLWRNORM
261 { POLLWRNORM, "POLLWRNORM" },
262#endif
263#ifdef POLLRDBAND
264 { POLLRDBAND, "POLLRDBAND" },
265#endif
266#ifdef POLLWRBAND
267 { POLLWRBAND, "POLLWRBAND" },
268#endif
269 { POLLERR, "POLLERR" },
270 { POLLHUP, "POLLHUP" },
271 { POLLNVAL, "POLLNVAL" },
272 { 0, NULL },
273};
274
275int
276sys_poll(tcp)
277struct tcb *tcp;
278{
279 struct pollfd *pollp;
280
281 if (exiting(tcp)) {
282 int i;
283 int nfds = tcp->u_arg[1];
284
285 if (nfds <= 0) {
286 tprintf("%#lx, %d, %ld\n",
287 tcp->u_arg[0], nfds, tcp->u_arg[2]);
288 return 0;
289 }
290 pollp = (struct pollfd *) malloc(nfds * sizeof(*pollp));
291 if (pollp == NULL) {
292 fprintf(stderr, "sys_poll: no memory\n");
293 tprintf("%#lx, %d, %ld",
294 tcp->u_arg[0], nfds, tcp->u_arg[2]);
295 return 0;
296 }
297 if (umoven(tcp, tcp->u_arg[0],
298 (nfds * sizeof(*pollp)), (char *) pollp) < 0) {
299 tprintf("%#lx", tcp->u_arg[0]);
300 }
301 else {
302 tprintf("[");
303 for (i = 0; i < nfds; i++) {
304 if (i)
305 tprintf(", ");
306 if (pollp[i].fd < 0) {
307 tprintf("{fd=%d}", pollp[i].fd);
308 continue;
309 }
310 tprintf("{fd=%d, events=", pollp[i].fd);
311 if (!printflags(pollflags, pollp[i].events))
312 tprintf("0");
313 if (!syserror(tcp) && pollp[i].revents) {
314 tprintf(", revents=");
315 if (!printflags(pollflags,
316 pollp[i].revents))
317 tprintf("0");
318 }
319 tprintf("}");
320 }
321 tprintf("]");
322 }
323 tprintf(", %d, ", nfds);
324#ifdef INFTIM
325 if (tcp->u_arg[2] == INFTIM)
326 tprintf("INFTIM");
327 else
328#endif
329 tprintf("%ld", tcp->u_arg[2]);
330 free(pollp);
331 }
332 return 0;
333}
334
335#ifndef linux
336
337static struct xlat stream_flush_options[] = {
338 { FLUSHR, "FLUSHR" },
339 { FLUSHW, "FLUSHW" },
340 { FLUSHRW, "FLUSHRW" },
341#ifdef FLUSHBAND
342 { FLUSHBAND, "FLUSHBAND" },
343#endif
344 { 0, NULL },
345};
346
347static struct xlat stream_setsig_flags[] = {
348 { S_INPUT, "S_INPUT" },
349 { S_HIPRI, "S_HIPRI" },
350 { S_OUTPUT, "S_OUTPUT" },
351 { S_MSG, "S_MSG" },
352#ifdef S_ERROR
353 { S_ERROR, "S_ERROR" },
354#endif
355#ifdef S_HANGUP
356 { S_HANGUP, "S_HANGUP" },
357#endif
358#ifdef S_RDNORM
359 { S_RDNORM, "S_RDNORM" },
360#endif
361#ifdef S_WRNORM
362 { S_WRNORM, "S_WRNORM" },
363#endif
364#ifdef S_RDBAND
365 { S_RDBAND, "S_RDBAND" },
366#endif
367#ifdef S_WRBAND
368 { S_WRBAND, "S_WRBAND" },
369#endif
370#ifdef S_BANDURG
371 { S_BANDURG, "S_BANDURG" },
372#endif
373 { 0, NULL },
374};
375
376static struct xlat stream_read_options[] = {
377 { RNORM, "RNORM" },
378 { RMSGD, "RMSGD" },
379 { RMSGN, "RMSGN" },
380 { 0, NULL },
381};
382
383static struct xlat stream_read_flags[] = {
384#ifdef RPROTDAT
385 { RPROTDAT, "RPROTDAT" },
386#endif
387#ifdef RPROTDIS
388 { RPROTDIS, "RPROTDIS" },
389#endif
390#ifdef RPROTNORM
391 { RPROTNORM, "RPROTNORM" },
392#endif
393 { 0, NULL },
394};
395
396#ifndef RMODEMASK
397#define RMODEMASK (~0)
398#endif
399
400#ifdef I_SWROPT
401static struct xlat stream_write_flags[] = {
402 { SNDZERO, "SNDZERO" },
403 { SNDPIPE, "SNDPIPE" },
404 { 0, NULL },
405};
406#endif /* I_SWROPT */
407
408#ifdef I_ATMARK
409static struct xlat stream_atmark_options[] = {
410 { ANYMARK, "ANYMARK" },
411 { LASTMARK, "LASTMARK" },
412 { 0, NULL },
413};
414#endif /* I_ATMARK */
415
416#ifdef TI_BIND
417static struct xlat transport_user_options[] = {
418 { T_CONN_REQ, "T_CONN_REQ" },
419 { T_CONN_RES, "T_CONN_RES" },
420 { T_DISCON_REQ, "T_DISCON_REQ" },
421 { T_DATA_REQ, "T_DATA_REQ" },
422 { T_EXDATA_REQ, "T_EXDATA_REQ" },
423 { T_INFO_REQ, "T_INFO_REQ" },
424 { T_BIND_REQ, "T_BIND_REQ" },
425 { T_UNBIND_REQ, "T_UNBIND_REQ" },
426 { T_UNITDATA_REQ,"T_UNITDATA_REQ"},
427 { T_OPTMGMT_REQ,"T_OPTMGMT_REQ" },
428 { T_ORDREL_REQ, "T_ORDREL_REQ" },
429 { 0, NULL },
430};
431
432static struct xlat transport_provider_options[] = {
433 { T_CONN_IND, "T_CONN_IND" },
434 { T_CONN_CON, "T_CONN_CON" },
435 { T_DISCON_IND, "T_DISCON_IND" },
436 { T_DATA_IND, "T_DATA_IND" },
437 { T_EXDATA_IND, "T_EXDATA_IND" },
438 { T_INFO_ACK, "T_INFO_ACK" },
439 { T_BIND_ACK, "T_BIND_ACK" },
440 { T_ERROR_ACK, "T_ERROR_ACK" },
441 { T_OK_ACK, "T_OK_ACK" },
442 { T_UNITDATA_IND,"T_UNITDATA_IND"},
443 { T_UDERROR_IND,"T_UDERROR_IND" },
444 { T_OPTMGMT_ACK,"T_OPTMGMT_ACK" },
445 { T_ORDREL_IND, "T_ORDREL_IND" },
446 { 0, NULL },
447};
448#endif /* TI_BIND */
449
450static int
451internal_stream_ioctl(tcp, arg)
452struct tcb *tcp;
453int arg;
454{
455 struct strioctl si;
456 char *name;
457 int in_and_out;
458#ifdef SI_GETUDATA
459 struct si_udata udata;
460#endif /* SI_GETUDATA */
461
462 if (!arg)
463 return 0;
464 if (umove(tcp, arg, &si) < 0) {
465 if (entering(tcp))
466 tprintf(", {...}");
467 return 1;
468 }
469 if (entering(tcp)) {
470 name = ioctl_lookup(si.ic_cmd);
471 if (name)
472 tprintf(", {ic_cmd=%s", name);
473 else
474 tprintf(", {ic_cmd=%#x", si.ic_cmd);
475 if (si.ic_timout == INFTIM)
476 tprintf(", ic_timout=INFTIM, ");
477 else
478 tprintf(" ic_timout=%d, ", si.ic_timout);
479 }
480 in_and_out = 1;
481 switch (si.ic_cmd) {
482#ifdef SI_GETUDATA
483 case SI_GETUDATA:
484 in_and_out = 0;
485 break;
486#endif /* SI_GETUDATA */
487 }
488 if (in_and_out) {
489 if (entering(tcp))
490 tprintf("/* in */ ");
491 else
492 tprintf(", /* out */ ");
493 }
494 if (in_and_out || entering(tcp))
495 tprintf("ic_len=%d, ic_dp=", si.ic_len);
496 switch (si.ic_cmd) {
497#ifdef TI_BIND
498 case TI_BIND:
499 /* in T_BIND_REQ, out T_BIND_ACK */
500 if (entering(tcp)) {
501 struct T_bind_req data;
502
503#if 0
504 tprintf("struct T_bind_req ");
505#endif
506 if (umove(tcp, (int) si.ic_dp, &data) < 0)
507 tprintf("{...}");
508 else {
509 tprintf("{PRIM_type=");
510 printxval(transport_user_options,
511 data.PRIM_type, "T_???");
512 tprintf(", ADDR_length=%ld, ADDR_offset=%ld",
513 data.ADDR_length, data.ADDR_offset);
514 tprintf(", CONIND_number=%ld}",
515 data.CONIND_number);
516 }
517 }
518 else {
519 struct T_bind_ack data;
520
521#if 0
522 tprintf("struct T_bind_ack ");
523#endif
524 if (umove(tcp, (int) si.ic_dp, &data) < 0)
525 tprintf("{...}");
526 else {
527 tprintf("[");
528 tprintf("{PRIM_type=");
529 printxval(transport_provider_options,
530 data.PRIM_type, "T_???");
531 tprintf(", ADDR_length=%ld, ADDR_offset=%ld",
532 data.ADDR_length, data.ADDR_offset);
533 tprintf(", CONIND_number=%ld}",
534 data.CONIND_number);
535 tprintf(", ");
536 printstr(tcp,
537 (int) si.ic_dp + data.ADDR_offset,
538 data.ADDR_length);
539 tprintf("]");
540 }
541 }
542 break;
543#endif /* TI_BIND */
544#if 0
545#ifdef TI_UNBIND
546 case TI_UNBIND:
547 /* in T_UNBIND_REQ, out T_OK_ACK */
548 break;
549#endif /* TI_UNBIND */
550#ifdef TI_GETINFO
551 case TI_GETINFO:
552 /* in T_INFO_REQ, out T_INFO_ACK */
553 break;
554#endif /* TI_GETINFO */
555#ifdef TI_OPTMGMT
556 case TI_OPTMGMT:
557 /* in T_OPTMGMT_REQ, out T_OPTMGMT_ACK */
558 break;
559#endif /* TI_OPTMGMT */
560#endif
561#ifdef SI_GETUDATA
562 case SI_GETUDATA:
563 if (entering(tcp))
564 break;
565#if 0
566 tprintf("struct si_udata ");
567#endif
568 if (umove(tcp, (int) si.ic_dp, &udata) < 0)
569 tprintf("{...}");
570 else {
571 tprintf("{tidusize=%d, addrsize=%d, ",
572 udata.tidusize, udata.addrsize);
573 tprintf("optsize=%d, etsdusize=%d, ",
574 udata.optsize, udata.etsdusize);
575 tprintf("servtype=%d, so_state=%d, ",
576 udata.servtype, udata.so_state);
577 tprintf("so_options=%d", udata.so_options);
578#if 0
579 tprintf(", tsdusize=%d", udata.tsdusize);
580#endif
581 tprintf("}");
582 }
583 break;
584#endif /* SI_GETUDATA */
585 default:
586 printstr(tcp, (int) si.ic_dp, si.ic_len);
587 break;
588 }
589 if (exiting(tcp))
590 tprintf("}");
591 return 1;
592}
593
594int
595stream_ioctl(tcp, code, arg)
596struct tcb *tcp;
597int code, arg;
598{
599#ifdef I_LIST
600 int i;
601#endif
602 int val;
603#ifdef I_FLUSHBAND
604 struct bandinfo bi;
605#endif
606 struct strpeek sp;
607 struct strfdinsert sfi;
608 struct strrecvfd srf;
609#ifdef I_LIST
610 struct str_list sl;
611#endif
612
613 /* I_STR is a special case because the data is read & written. */
614 if (code == I_STR)
615 return internal_stream_ioctl(tcp, arg);
616 if (entering(tcp))
617 return 0;
618
619 switch (code) {
620 case I_PUSH:
621 case I_LOOK:
622 case I_FIND:
623 /* arg is a string */
624 tprintf(", ");
625 printpath(tcp, arg);
626 return 1;
627 case I_POP:
628 /* doesn't take an argument */
629 return 1;
630 case I_FLUSH:
631 /* argument is an option */
632 tprintf(", ");
633 printxval(stream_flush_options, arg, "FLUSH???");
634 return 1;
635#ifdef I_FLUSHBAND
636 case I_FLUSHBAND:
637 /* argument is a pointer to a bandinfo struct */
638 if (umove(tcp, arg, &bi) < 0)
639 tprintf(", {...}");
640 else {
641 tprintf(", {bi_pri=%d, bi_flag=", bi.bi_pri);
642 if (!printflags(stream_flush_options, bi.bi_flag))
643 tprintf("0");
644 tprintf("}");
645 }
646 return 1;
647#endif /* I_FLUSHBAND */
648 case I_SETSIG:
649 /* argument is a set of flags */
650 tprintf(", ");
651 if (!printflags(stream_setsig_flags, arg))
652 tprintf("0");
653 return 1;
654 case I_GETSIG:
655 /* argument is a pointer to a set of flags */
656 if (syserror(tcp))
657 return 0;
658 tprintf(", [");
659 if (umove(tcp, arg, &val) < 0)
660 tprintf("?");
661 else if (!printflags(stream_setsig_flags, val))
662 tprintf("0");
663 tprintf("]");
664 return 1;
665 case I_PEEK:
666 /* argument is a pointer to a strpeek structure */
667 if (syserror(tcp) || !arg)
668 return 0;
669 if (umove(tcp, arg, &sp) < 0) {
670 tprintf(", {...}");
671 return 1;
672 }
673 tprintf(", {ctlbuf=");
674 printstrbuf(tcp, &sp.ctlbuf, 1);
675 tprintf(", databuf=");
676 printstrbuf(tcp, &sp.databuf, 1);
677 if (!printflags(msgflags, sp.flags))
678 tprintf("0");
679 return 1;
680 case I_SRDOPT:
681 /* argument is an option with flags */
682 tprintf(", ");
683 printxval(stream_read_options, arg & RMODEMASK, "R???");
684 addflags(stream_read_flags, arg & ~RMODEMASK);
685 return 1;
686 case I_GRDOPT:
687 /* argument is an pointer to an option with flags */
688 if (syserror(tcp))
689 return 0;
690 tprintf(", [");
691 if (umove(tcp, arg, &val) < 0)
692 tprintf("?");
693 else {
694 printxval(stream_read_options,
695 arg & RMODEMASK, "R???");
696 addflags(stream_read_flags, arg & ~RMODEMASK);
697 }
698 tprintf("]");
699 return 1;
700 case I_NREAD:
701#ifdef I_GETBAND
702 case I_GETBAND:
703#endif
704#ifdef I_SETCLTIME
705 case I_SETCLTIME:
706#endif
707#ifdef I_GETCLTIME
708 case I_GETCLTIME:
709#endif
710 /* argument is a pointer to a decimal integer */
711 if (syserror(tcp))
712 return 0;
713 tprintf(", ");
714 printnum(tcp, arg, "%d");
715 return 1;
716 case I_FDINSERT:
717 /* argument is a pointer to a strfdinsert structure */
718 if (syserror(tcp) || !arg)
719 return 0;
720 if (umove(tcp, arg, &sfi) < 0) {
721 tprintf(", {...}");
722 return 1;
723 }
724 tprintf(", {ctlbuf=");
725 printstrbuf(tcp, &sfi.ctlbuf, 1);
726 tprintf(", databuf=");
727 printstrbuf(tcp, &sfi.databuf, 1);
728 if (!printflags(msgflags, sfi.flags))
729 tprintf("0");
730 tprintf(", filedes=%d, offset=%d}", sfi.fildes, sfi.offset);
731 return 1;
732#ifdef I_SWROPT
733 case I_SWROPT:
734 /* argument is a set of flags */
735 tprintf(", ");
736 if (!printflags(stream_write_flags, arg))
737 tprintf("0");
738 return 1;
739#endif /* I_SWROPT */
740#ifdef I_GWROPT
741 case I_GWROPT:
742 /* argument is an pointer to an option with flags */
743 if (syserror(tcp))
744 return 0;
745 tprintf(", [");
746 if (umove(tcp, arg, &val) < 0)
747 tprintf("?");
748 else if (!printflags(stream_write_flags, arg))
749 tprintf("0");
750 tprintf("]");
751 return 1;
752#endif /* I_GWROPT */
753 case I_SENDFD:
754#ifdef I_CKBAND
755 case I_CKBAND:
756#endif
757#ifdef I_CANPUT
758 case I_CANPUT:
759#endif
760 case I_LINK:
761 case I_UNLINK:
762 case I_PLINK:
763 case I_PUNLINK:
764 /* argument is a decimal integer */
765 tprintf(", %d", arg);
766 return 1;
767 case I_RECVFD:
768 /* argument is a pointer to a strrecvfd structure */
769 if (syserror(tcp) || !arg)
770 return 0;
771 if (umove(tcp, arg, &srf) < 0) {
772 tprintf(", {...}");
773 return 1;
774 }
775 tprintf(", {fd=%d, uid=%lu, gid=%lu}", srf.fd,
776 (unsigned long) srf.uid, (unsigned long) srf.gid);
777 return 1;
778#ifdef I_LIST
779 case I_LIST:
780 if (syserror(tcp))
781 return 0;
782 if (arg == 0) {
783 tprintf(", NULL");
784 return 1;
785 }
786 if (umove(tcp, arg, &sl) < 0) {
787 tprintf(", {...}");
788 return 1;
789 }
790 tprintf(", {sl_nmods=%d, sl_modlist=[", sl.sl_nmods);
791 for (i = 0; i < tcp->u_rval; i++) {
792 if (i)
793 tprintf(", ");
794 printpath(tcp, (int) sl.sl_modlist[i].l_name);
795 }
796 tprintf("]}");
797 return 1;
798#endif /* I_LIST */
799#ifdef I_ATMARK
800 case I_ATMARK:
801 tprintf(", ");
802 printxval(stream_atmark_options, arg, "???MARK");
803 return 1;
804#endif /* I_ATMARK */
805 default:
806 return 0;
807 }
808}
809
810#endif /* linux */
811
812#endif /* LINUXSPARC && linux */
813