b63256e69b
* bjm.c: Fix tabulation (such as extra spaces before tabs), convert punctuation where it deviates from prevalent form elsewhere in strace code, convert sizeof and offsetof where it deviates from from prevalent form, remove space between function/macro/array names and (parameters) or [index], add space between "if" and (condition), correct non-standard or wrong indentaion. * defs.h: Likewise * desc.c: Likewise * file.c: Likewise * ipc.c: Likewise * linux/arm/syscallent.h: Likewise * linux/avr32/syscallent.h: Likewise * linux/hppa/syscallent.h: Likewise * linux/i386/syscallent.h: Likewise * linux/ioctlsort.c: Likewise * linux/m68k/syscallent.h: Likewise * linux/microblaze/syscallent.h: Likewise * linux/powerpc/syscallent.h: Likewise * linux/s390/syscallent.h: Likewise * linux/s390x/syscallent.h: Likewise * linux/sh/syscallent.h: Likewise * linux/sh64/syscallent.h: Likewise * linux/tile/syscallent.h: Likewise * linux/x86_64/syscallent.h: Likewise * mem.c: Likewise * net.c: Likewise * pathtrace.c: Likewise * process.c: Likewise * signal.c: Likewise * sock.c: Likewise * strace.c: Likewise * stream.c: Likewise * sunos4/syscall.h: Likewise * sunos4/syscallent.h: Likewise * svr4/syscall.h: Likewise * svr4/syscallent.h: Likewise * syscall.c: Likewise * system.c: Likewise * test/childthread.c: Likewise * test/leaderkill.c: Likewise * test/skodic.c: Likewise * time.c: Likewise * util.c: Likewise Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
1376 lines
30 KiB
C
1376 lines
30 KiB
C
/*
|
|
* Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
|
|
* Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include "defs.h"
|
|
#include <sys/syscall.h>
|
|
|
|
#ifdef HAVE_POLL_H
|
|
#include <poll.h>
|
|
#endif
|
|
#ifdef HAVE_SYS_POLL_H
|
|
#include <sys/poll.h>
|
|
#endif
|
|
#ifdef HAVE_STROPTS_H
|
|
#include <stropts.h>
|
|
#endif
|
|
#ifdef HAVE_SYS_CONF_H
|
|
#include <sys/conf.h>
|
|
#endif
|
|
#ifdef HAVE_SYS_STREAM_H
|
|
#include <sys/stream.h>
|
|
#endif
|
|
#ifdef HAVE_SYS_TIHDR_H
|
|
#include <sys/tihdr.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_SYS_STREAM_H) || defined(LINUX) || defined(FREEBSD)
|
|
|
|
#ifndef HAVE_STROPTS_H
|
|
#define RS_HIPRI 1
|
|
struct strbuf {
|
|
int maxlen; /* no. of bytes in buffer */
|
|
int len; /* no. of bytes returned */
|
|
const char *buf; /* pointer to data */
|
|
};
|
|
#define MORECTL 1
|
|
#define MOREDATA 2
|
|
#endif /* !HAVE_STROPTS_H */
|
|
|
|
#ifdef HAVE_SYS_TIUSER_H
|
|
#include <sys/tiuser.h>
|
|
#include <sys/sockmod.h>
|
|
#include <sys/timod.h>
|
|
#endif /* HAVE_SYS_TIUSER_H */
|
|
|
|
#ifndef FREEBSD
|
|
static const struct xlat msgflags[] = {
|
|
{ RS_HIPRI, "RS_HIPRI" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
|
|
static void
|
|
printstrbuf(struct tcb *tcp, struct strbuf *sbp, int getting)
|
|
{
|
|
if (sbp->maxlen == -1 && getting)
|
|
tprintf("{maxlen=-1}");
|
|
else {
|
|
tprintf("{");
|
|
if (getting)
|
|
tprintf("maxlen=%d, ", sbp->maxlen);
|
|
tprintf("len=%d, buf=", sbp->len);
|
|
printstr(tcp, (unsigned long) sbp->buf, sbp->len);
|
|
tprintf("}");
|
|
}
|
|
}
|
|
|
|
static void
|
|
printstrbufarg(struct tcb *tcp, int arg, int getting)
|
|
{
|
|
struct strbuf buf;
|
|
|
|
if (arg == 0)
|
|
tprintf("NULL");
|
|
else if (umove(tcp, arg, &buf) < 0)
|
|
tprintf("{...}");
|
|
else
|
|
printstrbuf(tcp, &buf, getting);
|
|
tprintf(", ");
|
|
}
|
|
|
|
int
|
|
sys_putmsg(struct tcb *tcp)
|
|
{
|
|
int i;
|
|
|
|
if (entering(tcp)) {
|
|
/* fd */
|
|
tprintf("%ld, ", tcp->u_arg[0]);
|
|
/* control and data */
|
|
for (i = 1; i < 3; i++)
|
|
printstrbufarg(tcp, tcp->u_arg[i], 0);
|
|
/* flags */
|
|
printflags(msgflags, tcp->u_arg[3], "RS_???");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4) || defined(SVR4)
|
|
int
|
|
sys_getmsg(struct tcb *tcp)
|
|
{
|
|
int i, flags;
|
|
|
|
if (entering(tcp)) {
|
|
/* fd */
|
|
tprintf("%lu, ", tcp->u_arg[0]);
|
|
} else {
|
|
if (syserror(tcp)) {
|
|
tprintf("%#lx, %#lx, %#lx",
|
|
tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
|
|
return 0;
|
|
}
|
|
/* control and data */
|
|
for (i = 1; i < 3; i++)
|
|
printstrbufarg(tcp, tcp->u_arg[i], 1);
|
|
/* pointer to flags */
|
|
if (tcp->u_arg[3] == 0)
|
|
tprintf("NULL");
|
|
else if (umove(tcp, tcp->u_arg[3], &flags) < 0)
|
|
tprintf("[?]");
|
|
else {
|
|
tprintf("[");
|
|
printflags(msgflags, flags, "RS_???");
|
|
tprintf("]");
|
|
}
|
|
/* decode return value */
|
|
switch (tcp->u_rval) {
|
|
case MORECTL:
|
|
tcp->auxstr = "MORECTL";
|
|
break;
|
|
case MORECTL|MOREDATA:
|
|
tcp->auxstr = "MORECTL|MOREDATA";
|
|
break;
|
|
case MOREDATA:
|
|
tcp->auxstr = "MORECTL";
|
|
break;
|
|
default:
|
|
tcp->auxstr = NULL;
|
|
break;
|
|
}
|
|
}
|
|
return RVAL_HEX | RVAL_STR;
|
|
}
|
|
#endif /* SPARC || SPARC64 || SUNOS4 || SVR4 */
|
|
|
|
#if defined SYS_putpmsg || defined SYS_getpmsg
|
|
static const struct xlat pmsgflags[] = {
|
|
#ifdef MSG_HIPRI
|
|
{ MSG_HIPRI, "MSG_HIPRI" },
|
|
#endif
|
|
#ifdef MSG_AND
|
|
{ MSG_ANY, "MSG_ANY" },
|
|
#endif
|
|
#ifdef MSG_BAND
|
|
{ MSG_BAND, "MSG_BAND" },
|
|
#endif
|
|
{ 0, NULL },
|
|
};
|
|
#endif
|
|
|
|
#ifdef SYS_putpmsg
|
|
int
|
|
sys_putpmsg(struct tcb *tcp)
|
|
{
|
|
int i;
|
|
|
|
if (entering(tcp)) {
|
|
/* fd */
|
|
tprintf("%ld, ", tcp->u_arg[0]);
|
|
/* control and data */
|
|
for (i = 1; i < 3; i++)
|
|
printstrbufarg(tcp, tcp->u_arg[i], 0);
|
|
/* band */
|
|
tprintf("%ld, ", tcp->u_arg[3]);
|
|
/* flags */
|
|
printflags(pmsgflags, tcp->u_arg[4], "MSG_???");
|
|
}
|
|
return 0;
|
|
}
|
|
#endif /* SYS_putpmsg */
|
|
|
|
#ifdef SYS_getpmsg
|
|
int
|
|
sys_getpmsg(struct tcb *tcp)
|
|
{
|
|
int i, flags;
|
|
|
|
if (entering(tcp)) {
|
|
/* fd */
|
|
tprintf("%lu, ", tcp->u_arg[0]);
|
|
} else {
|
|
if (syserror(tcp)) {
|
|
tprintf("%#lx, %#lx, %#lx, %#lx", tcp->u_arg[1],
|
|
tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[4]);
|
|
return 0;
|
|
}
|
|
/* control and data */
|
|
for (i = 1; i < 3; i++)
|
|
printstrbufarg(tcp, tcp->u_arg[i], 1);
|
|
/* pointer to band */
|
|
printnum(tcp, tcp->u_arg[3], "%d");
|
|
tprintf(", ");
|
|
/* pointer to flags */
|
|
if (tcp->u_arg[4] == 0)
|
|
tprintf("NULL");
|
|
else if (umove(tcp, tcp->u_arg[4], &flags) < 0)
|
|
tprintf("[?]");
|
|
else {
|
|
tprintf("[");
|
|
printflags(pmsgflags, flags, "MSG_???");
|
|
tprintf("]");
|
|
}
|
|
/* decode return value */
|
|
switch (tcp->u_rval) {
|
|
case MORECTL:
|
|
tcp->auxstr = "MORECTL";
|
|
break;
|
|
case MORECTL|MOREDATA:
|
|
tcp->auxstr = "MORECTL|MOREDATA";
|
|
break;
|
|
case MOREDATA:
|
|
tcp->auxstr = "MORECTL";
|
|
break;
|
|
default:
|
|
tcp->auxstr = NULL;
|
|
break;
|
|
}
|
|
}
|
|
return RVAL_HEX | RVAL_STR;
|
|
}
|
|
#endif /* SYS_getpmsg */
|
|
|
|
#endif /* !FREEBSD */
|
|
|
|
|
|
#ifdef HAVE_SYS_POLL_H
|
|
|
|
static const struct xlat pollflags[] = {
|
|
#ifdef POLLIN
|
|
{ POLLIN, "POLLIN" },
|
|
{ POLLPRI, "POLLPRI" },
|
|
{ POLLOUT, "POLLOUT" },
|
|
#ifdef POLLRDNORM
|
|
{ POLLRDNORM, "POLLRDNORM" },
|
|
#endif
|
|
#ifdef POLLWRNORM
|
|
{ POLLWRNORM, "POLLWRNORM" },
|
|
#endif
|
|
#ifdef POLLRDBAND
|
|
{ POLLRDBAND, "POLLRDBAND" },
|
|
#endif
|
|
#ifdef POLLWRBAND
|
|
{ POLLWRBAND, "POLLWRBAND" },
|
|
#endif
|
|
{ POLLERR, "POLLERR" },
|
|
{ POLLHUP, "POLLHUP" },
|
|
{ POLLNVAL, "POLLNVAL" },
|
|
#endif
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static int
|
|
decode_poll(struct tcb *tcp, long pts)
|
|
{
|
|
struct pollfd fds;
|
|
unsigned nfds;
|
|
unsigned long size, start, cur, end, abbrev_end;
|
|
int failed = 0;
|
|
|
|
if (entering(tcp)) {
|
|
nfds = tcp->u_arg[1];
|
|
size = sizeof(fds) * nfds;
|
|
start = tcp->u_arg[0];
|
|
end = start + size;
|
|
if (nfds == 0 || size / sizeof(fds) != nfds || end < start) {
|
|
tprintf("%#lx, %d, ",
|
|
tcp->u_arg[0], nfds);
|
|
return 0;
|
|
}
|
|
if (abbrev(tcp)) {
|
|
abbrev_end = start + max_strlen * sizeof(fds);
|
|
if (abbrev_end < start)
|
|
abbrev_end = end;
|
|
} else {
|
|
abbrev_end = end;
|
|
}
|
|
tprintf("[");
|
|
for (cur = start; cur < end; cur += sizeof(fds)) {
|
|
if (cur > start)
|
|
tprintf(", ");
|
|
if (cur >= abbrev_end) {
|
|
tprintf("...");
|
|
break;
|
|
}
|
|
if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
|
|
tprintf("?");
|
|
failed = 1;
|
|
break;
|
|
}
|
|
if (fds.fd < 0) {
|
|
tprintf("{fd=%d}", fds.fd);
|
|
continue;
|
|
}
|
|
tprintf("{fd=");
|
|
printfd(tcp, fds.fd);
|
|
tprintf(", events=");
|
|
printflags(pollflags, fds.events, "POLL???");
|
|
tprintf("}");
|
|
}
|
|
tprintf("]");
|
|
if (failed)
|
|
tprintf(" %#lx", start);
|
|
tprintf(", %d, ", nfds);
|
|
return 0;
|
|
} else {
|
|
static char outstr[1024];
|
|
char str[64];
|
|
const char *flagstr;
|
|
unsigned int cumlen;
|
|
|
|
if (syserror(tcp))
|
|
return 0;
|
|
if (tcp->u_rval == 0) {
|
|
tcp->auxstr = "Timeout";
|
|
return RVAL_STR;
|
|
}
|
|
|
|
nfds = tcp->u_arg[1];
|
|
size = sizeof(fds) * nfds;
|
|
start = tcp->u_arg[0];
|
|
end = start + size;
|
|
if (nfds == 0 || size / sizeof(fds) != nfds || end < start)
|
|
return 0;
|
|
if (abbrev(tcp)) {
|
|
abbrev_end = start + max_strlen * sizeof(fds);
|
|
if (abbrev_end < start)
|
|
abbrev_end = end;
|
|
} else {
|
|
abbrev_end = end;
|
|
}
|
|
|
|
outstr[0] = '\0';
|
|
cumlen = 0;
|
|
|
|
for (cur = start; cur < end; cur += sizeof(fds)) {
|
|
if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
|
|
++cumlen;
|
|
if (cumlen < sizeof(outstr))
|
|
strcat(outstr, "?");
|
|
failed = 1;
|
|
break;
|
|
}
|
|
if (!fds.revents)
|
|
continue;
|
|
if (!cumlen) {
|
|
++cumlen;
|
|
strcat(outstr, "[");
|
|
} else {
|
|
cumlen += 2;
|
|
if (cumlen < sizeof(outstr))
|
|
strcat(outstr, ", ");
|
|
}
|
|
if (cur >= abbrev_end) {
|
|
cumlen += 3;
|
|
if (cumlen < sizeof(outstr))
|
|
strcat(outstr, "...");
|
|
break;
|
|
}
|
|
sprintf(str, "{fd=%d, revents=", fds.fd);
|
|
flagstr = sprintflags("", pollflags, fds.revents);
|
|
cumlen += strlen(str) + strlen(flagstr) + 1;
|
|
if (cumlen < sizeof(outstr)) {
|
|
strcat(outstr, str);
|
|
strcat(outstr, flagstr);
|
|
strcat(outstr, "}");
|
|
}
|
|
}
|
|
if (failed)
|
|
return 0;
|
|
|
|
if (cumlen && ++cumlen < sizeof(outstr))
|
|
strcat(outstr, "]");
|
|
|
|
if (pts) {
|
|
char str[128];
|
|
|
|
sprintf(str, "%sleft ", cumlen ? ", " : "");
|
|
sprint_timespec(str + strlen(str), tcp, pts);
|
|
if ((cumlen += strlen(str)) < sizeof(outstr))
|
|
strcat(outstr, str);
|
|
}
|
|
|
|
if (!outstr[0])
|
|
return 0;
|
|
|
|
tcp->auxstr = outstr;
|
|
return RVAL_STR;
|
|
}
|
|
}
|
|
|
|
int
|
|
sys_poll(struct tcb *tcp)
|
|
{
|
|
int rc = decode_poll(tcp, 0);
|
|
if (entering(tcp)) {
|
|
#ifdef INFTIM
|
|
if (tcp->u_arg[2] == INFTIM)
|
|
tprintf("INFTIM");
|
|
else
|
|
#endif
|
|
tprintf("%ld", tcp->u_arg[2]);
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
#ifdef LINUX
|
|
int
|
|
sys_ppoll(struct tcb *tcp)
|
|
{
|
|
int rc = decode_poll(tcp, tcp->u_arg[2]);
|
|
if (entering(tcp)) {
|
|
print_timespec(tcp, tcp->u_arg[2]);
|
|
tprintf(", ");
|
|
print_sigset(tcp, tcp->u_arg[3], 0);
|
|
tprintf(", %lu", tcp->u_arg[4]);
|
|
}
|
|
return rc;
|
|
}
|
|
#endif
|
|
|
|
#else /* !HAVE_SYS_POLL_H */
|
|
int
|
|
sys_poll(struct tcb *tcp)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if !defined(LINUX) && !defined(FREEBSD)
|
|
|
|
static const struct xlat stream_flush_options[] = {
|
|
{ FLUSHR, "FLUSHR" },
|
|
{ FLUSHW, "FLUSHW" },
|
|
{ FLUSHRW, "FLUSHRW" },
|
|
#ifdef FLUSHBAND
|
|
{ FLUSHBAND, "FLUSHBAND" },
|
|
#endif
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const struct xlat stream_setsig_flags[] = {
|
|
{ S_INPUT, "S_INPUT" },
|
|
{ S_HIPRI, "S_HIPRI" },
|
|
{ S_OUTPUT, "S_OUTPUT" },
|
|
{ S_MSG, "S_MSG" },
|
|
#ifdef S_ERROR
|
|
{ S_ERROR, "S_ERROR" },
|
|
#endif
|
|
#ifdef S_HANGUP
|
|
{ S_HANGUP, "S_HANGUP" },
|
|
#endif
|
|
#ifdef S_RDNORM
|
|
{ S_RDNORM, "S_RDNORM" },
|
|
#endif
|
|
#ifdef S_WRNORM
|
|
{ S_WRNORM, "S_WRNORM" },
|
|
#endif
|
|
#ifdef S_RDBAND
|
|
{ S_RDBAND, "S_RDBAND" },
|
|
#endif
|
|
#ifdef S_WRBAND
|
|
{ S_WRBAND, "S_WRBAND" },
|
|
#endif
|
|
#ifdef S_BANDURG
|
|
{ S_BANDURG, "S_BANDURG" },
|
|
#endif
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const struct xlat stream_read_options[] = {
|
|
{ RNORM, "RNORM" },
|
|
{ RMSGD, "RMSGD" },
|
|
{ RMSGN, "RMSGN" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const struct xlat stream_read_flags[] = {
|
|
#ifdef RPROTDAT
|
|
{ RPROTDAT, "RPROTDAT" },
|
|
#endif
|
|
#ifdef RPROTDIS
|
|
{ RPROTDIS, "RPROTDIS" },
|
|
#endif
|
|
#ifdef RPROTNORM
|
|
{ RPROTNORM, "RPROTNORM" },
|
|
#endif
|
|
{ 0, NULL },
|
|
};
|
|
|
|
#ifndef RMODEMASK
|
|
#define RMODEMASK (~0)
|
|
#endif
|
|
|
|
#ifdef I_SWROPT
|
|
static const struct xlat stream_write_flags[] = {
|
|
{ SNDZERO, "SNDZERO" },
|
|
{ SNDPIPE, "SNDPIPE" },
|
|
{ 0, NULL },
|
|
};
|
|
#endif /* I_SWROPT */
|
|
|
|
#ifdef I_ATMARK
|
|
static const struct xlat stream_atmark_options[] = {
|
|
{ ANYMARK, "ANYMARK" },
|
|
{ LASTMARK, "LASTMARK" },
|
|
{ 0, NULL },
|
|
};
|
|
#endif /* I_ATMARK */
|
|
|
|
#ifdef TI_BIND
|
|
static const struct xlat transport_user_options[] = {
|
|
{ T_CONN_REQ, "T_CONN_REQ" },
|
|
{ T_CONN_RES, "T_CONN_RES" },
|
|
{ T_DISCON_REQ, "T_DISCON_REQ" },
|
|
{ T_DATA_REQ, "T_DATA_REQ" },
|
|
{ T_EXDATA_REQ, "T_EXDATA_REQ" },
|
|
{ T_INFO_REQ, "T_INFO_REQ" },
|
|
{ T_BIND_REQ, "T_BIND_REQ" },
|
|
{ T_UNBIND_REQ, "T_UNBIND_REQ" },
|
|
{ T_UNITDATA_REQ,"T_UNITDATA_REQ"},
|
|
{ T_OPTMGMT_REQ,"T_OPTMGMT_REQ" },
|
|
{ T_ORDREL_REQ, "T_ORDREL_REQ" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const struct xlat transport_user_flags[] = {
|
|
{ 0, "0" },
|
|
{ T_MORE, "T_MORE" },
|
|
{ T_EXPEDITED, "T_EXPEDITED" },
|
|
{ T_NEGOTIATE, "T_NEGOTIATE" },
|
|
{ T_CHECK, "T_CHECK" },
|
|
{ T_DEFAULT, "T_DEFAULT" },
|
|
{ T_SUCCESS, "T_SUCCESS" },
|
|
{ T_FAILURE, "T_FAILURE" },
|
|
{ T_CURRENT, "T_CURRENT" },
|
|
{ T_PARTSUCCESS,"T_PARTSUCCESS" },
|
|
{ T_READONLY, "T_READONLY" },
|
|
{ T_NOTSUPPORT, "T_NOTSUPPORT" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
|
|
#ifdef HAVE_STRUCT_T_OPTHDR
|
|
|
|
static const struct xlat xti_level[] = {
|
|
{ XTI_GENERIC, "XTI_GENERIC" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const struct xlat xti_generic[] = {
|
|
{ XTI_DEBUG, "XTI_DEBUG" },
|
|
{ XTI_LINGER, "XTI_LINGER" },
|
|
{ XTI_RCVBUF, "XTI_RCVBUF" },
|
|
{ XTI_RCVLOWAT, "XTI_RCVLOWAT" },
|
|
{ XTI_SNDBUF, "XTI_SNDBUF" },
|
|
{ XTI_SNDLOWAT, "XTI_SNDLOWAT" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
|
|
|
|
void
|
|
print_xti_optmgmt(struct tcb *tcp, long addr, int len)
|
|
{
|
|
int c = 0;
|
|
struct t_opthdr hdr;
|
|
|
|
while (len >= (int) sizeof hdr) {
|
|
if (umove(tcp, addr, &hdr) < 0) break;
|
|
if (c++) {
|
|
tprintf(", ");
|
|
}
|
|
else if (len > hdr.len + sizeof hdr) {
|
|
tprintf("[");
|
|
}
|
|
tprintf("{level=");
|
|
printxval(xti_level, hdr.level, "???");
|
|
tprintf(", name=");
|
|
switch (hdr.level) {
|
|
case XTI_GENERIC:
|
|
printxval(xti_generic, hdr.name, "XTI_???");
|
|
break;
|
|
default:
|
|
tprintf("%ld", hdr.name);
|
|
break;
|
|
}
|
|
tprintf(", status=");
|
|
printxval(transport_user_flags, hdr.status, "T_???");
|
|
addr += sizeof hdr;
|
|
len -= sizeof hdr;
|
|
if ((hdr.len -= sizeof hdr) > 0) {
|
|
if (hdr.len > len) break;
|
|
tprintf(", val=");
|
|
if (len == sizeof(int))
|
|
printnum(tcp, addr, "%d");
|
|
else
|
|
printstr(tcp, addr, hdr.len);
|
|
addr += hdr.len;
|
|
len -= hdr.len;
|
|
}
|
|
tprintf("}");
|
|
}
|
|
if (len > 0) {
|
|
if (c++) tprintf(", ");
|
|
printstr(tcp, addr, len);
|
|
}
|
|
if (c > 1) tprintf("]");
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
static void
|
|
print_optmgmt(struct tcb *tcp, long addr, int len)
|
|
{
|
|
/* We don't know how to tell if TLI (socket) or XTI
|
|
optmgmt is being used yet, assume TLI. */
|
|
#if defined (HAVE_STRUCT_OPTHDR)
|
|
print_sock_optmgmt(tcp, addr, len);
|
|
#elif defined (HAVE_STRUCT_T_OPTHDR)
|
|
print_xti_optmgmt(tcp, addr, len);
|
|
#else
|
|
printstr(tcp, addr, len);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct xlat service_type[] = {
|
|
{ T_COTS, "T_COTS" },
|
|
{ T_COTS_ORD, "T_COTS_ORD" },
|
|
{ T_CLTS, "T_CLTS" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const struct xlat ts_state[] = {
|
|
{ TS_UNBND, "TS_UNBND" },
|
|
{ TS_WACK_BREQ, "TS_WACK_BREQ" },
|
|
{ TS_WACK_UREQ, "TS_WACK_UREQ" },
|
|
{ TS_IDLE, "TS_IDLE" },
|
|
{ TS_WACK_OPTREQ,"TS_WACK_OPTREQ"},
|
|
{ TS_WACK_CREQ, "TS_WACK_CREQ" },
|
|
{ TS_WCON_CREQ, "TS_WCON_CREQ" },
|
|
{ TS_WRES_CIND, "TS_WRES_CIND" },
|
|
{ TS_WACK_CRES, "TS_WACK_CRES" },
|
|
{ TS_DATA_XFER, "TS_DATA_XFER" },
|
|
{ TS_WIND_ORDREL,"TS_WIND_ORDREL"},
|
|
{ TS_WREQ_ORDREL,"TS_WREQ_ORDREL"},
|
|
{ TS_WACK_DREQ6,"TS_WACK_DREQ6" },
|
|
{ TS_WACK_DREQ7,"TS_WACK_DREQ7" },
|
|
{ TS_WACK_DREQ9,"TS_WACK_DREQ9" },
|
|
{ TS_WACK_DREQ10,"TS_WACK_DREQ10"},
|
|
{ TS_WACK_DREQ11,"TS_WACK_DREQ11"},
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const struct xlat provider_flags[] = {
|
|
{ 0, "0" },
|
|
{ SENDZERO, "SENDZERO" },
|
|
{ EXPINLINE, "EXPINLINE" },
|
|
{ XPG4_1, "XPG4_1" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
|
|
static const struct xlat tli_errors[] = {
|
|
{ TBADADDR, "TBADADDR" },
|
|
{ TBADOPT, "TBADOPT" },
|
|
{ TACCES, "TACCES" },
|
|
{ TBADF, "TBADF" },
|
|
{ TNOADDR, "TNOADDR" },
|
|
{ TOUTSTATE, "TOUTSTATE" },
|
|
{ TBADSEQ, "TBADSEQ" },
|
|
{ TSYSERR, "TSYSERR" },
|
|
{ TLOOK, "TLOOK" },
|
|
{ TBADDATA, "TBADDATA" },
|
|
{ TBUFOVFLW, "TBUFOVFLW" },
|
|
{ TFLOW, "TFLOW" },
|
|
{ TNODATA, "TNODATA" },
|
|
{ TNODIS, "TNODIS" },
|
|
{ TNOUDERR, "TNOUDERR" },
|
|
{ TBADFLAG, "TBADFLAG" },
|
|
{ TNOREL, "TNOREL" },
|
|
{ TNOTSUPPORT, "TNOTSUPPORT" },
|
|
{ TSTATECHNG, "TSTATECHNG" },
|
|
{ TNOSTRUCTYPE, "TNOSTRUCTYPE" },
|
|
{ TBADNAME, "TBADNAME" },
|
|
{ TBADQLEN, "TBADQLEN" },
|
|
{ TADDRBUSY, "TADDRBUSY" },
|
|
{ TINDOUT, "TINDOUT" },
|
|
{ TPROVMISMATCH,"TPROVMISMATCH" },
|
|
{ TRESQLEN, "TRESQLEN" },
|
|
{ TRESADDR, "TRESADDR" },
|
|
{ TQFULL, "TQFULL" },
|
|
{ TPROTO, "TPROTO" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
|
|
static int
|
|
print_transport_message(struct tcb *tcp, int expect, long addr, int len)
|
|
{
|
|
union T_primitives m;
|
|
int c = 0;
|
|
|
|
if (len < sizeof m.type) goto dump;
|
|
|
|
if (umove(tcp, addr, &m.type) < 0) goto dump;
|
|
|
|
#define GET(type, struct) \
|
|
do { \
|
|
if (len < sizeof m.struct) goto dump; \
|
|
if (umove(tcp, addr, &m.struct) < 0) goto dump;\
|
|
tprintf("{"); \
|
|
if (expect != type) { \
|
|
++c; \
|
|
tprintf(#type); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
#define COMMA() \
|
|
do { if (c++) tprintf(", "); } while (0)
|
|
|
|
|
|
#define STRUCT(struct, elem, print) \
|
|
do { \
|
|
COMMA(); \
|
|
if (m.struct.elem##_length < 0 || \
|
|
m.struct.elem##_offset < sizeof m.struct || \
|
|
m.struct.elem##_offset + m.struct.elem##_length > len) \
|
|
{ \
|
|
tprintf(#elem "_length=%ld, " #elem "_offset=%ld",\
|
|
m.struct.elem##_length, \
|
|
m.struct.elem##_offset); \
|
|
} \
|
|
else { \
|
|
tprintf(#elem "="); \
|
|
print(tcp, \
|
|
addr + m.struct.elem##_offset, \
|
|
m.struct.elem##_length); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
#define ADDR(struct, elem) STRUCT(struct, elem, printstr)
|
|
|
|
switch (m.type) {
|
|
#ifdef T_CONN_REQ
|
|
case T_CONN_REQ: /* connect request */
|
|
GET(T_CONN_REQ, conn_req);
|
|
ADDR(conn_req, DEST);
|
|
ADDR(conn_req, OPT);
|
|
break;
|
|
#endif
|
|
#ifdef T_CONN_RES
|
|
case T_CONN_RES: /* connect response */
|
|
GET(T_CONN_RES, conn_res);
|
|
#ifdef HAVE_STRUCT_T_CONN_RES_QUEUE_PTR
|
|
COMMA();
|
|
tprintf("QUEUE=%p", m.conn_res.QUEUE_ptr);
|
|
#elif defined HAVE_STRUCT_T_CONN_RES_ACCEPTOR_ID
|
|
COMMA();
|
|
tprintf("ACCEPTOR=%#lx", m.conn_res.ACCEPTOR_id);
|
|
#endif
|
|
ADDR(conn_res, OPT);
|
|
COMMA();
|
|
tprintf("SEQ=%ld", m.conn_res.SEQ_number);
|
|
break;
|
|
#endif
|
|
#ifdef T_DISCON_REQ
|
|
case T_DISCON_REQ: /* disconnect request */
|
|
GET(T_DISCON_REQ, discon_req);
|
|
COMMA();
|
|
tprintf("SEQ=%ld", m.discon_req.SEQ_number);
|
|
break;
|
|
#endif
|
|
#ifdef T_DATA_REQ
|
|
case T_DATA_REQ: /* data request */
|
|
GET(T_DATA_REQ, data_req);
|
|
COMMA();
|
|
tprintf("MORE=%ld", m.data_req.MORE_flag);
|
|
break;
|
|
#endif
|
|
#ifdef T_EXDATA_REQ
|
|
case T_EXDATA_REQ: /* expedited data req */
|
|
GET(T_EXDATA_REQ, exdata_req);
|
|
COMMA();
|
|
tprintf("MORE=%ld", m.exdata_req.MORE_flag);
|
|
break;
|
|
#endif
|
|
#ifdef T_INFO_REQ
|
|
case T_INFO_REQ: /* information req */
|
|
GET(T_INFO_REQ, info_req);
|
|
break;
|
|
#endif
|
|
#ifdef T_BIND_REQ
|
|
case T_BIND_REQ: /* bind request */
|
|
#ifdef O_T_BIND_REQ
|
|
case O_T_BIND_REQ: /* Ugly xti/tli hack */
|
|
#endif
|
|
GET(T_BIND_REQ, bind_req);
|
|
ADDR(bind_req, ADDR);
|
|
COMMA();
|
|
tprintf("CONIND=%ld", m.bind_req.CONIND_number);
|
|
break;
|
|
#endif
|
|
#ifdef T_UNBIND_REQ
|
|
case T_UNBIND_REQ: /* unbind request */
|
|
GET(T_UNBIND_REQ, unbind_req);
|
|
break;
|
|
#endif
|
|
#ifdef T_UNITDATA_REQ
|
|
case T_UNITDATA_REQ: /* unitdata requset */
|
|
GET(T_UNITDATA_REQ, unitdata_req);
|
|
ADDR(unitdata_req, DEST);
|
|
ADDR(unitdata_req, OPT);
|
|
break;
|
|
#endif
|
|
#ifdef T_OPTMGMT_REQ
|
|
case T_OPTMGMT_REQ: /* manage opt req */
|
|
GET(T_OPTMGMT_REQ, optmgmt_req);
|
|
COMMA();
|
|
tprintf("MGMT=");
|
|
printflags(transport_user_flags, m.optmgmt_req.MGMT_flags,
|
|
"T_???");
|
|
STRUCT(optmgmt_req, OPT, print_optmgmt);
|
|
break;
|
|
#endif
|
|
#ifdef T_ORDREL_REQ
|
|
case T_ORDREL_REQ: /* orderly rel req */
|
|
GET(T_ORDREL_REQ, ordrel_req);
|
|
break;
|
|
#endif
|
|
#ifdef T_CONN_IND
|
|
case T_CONN_IND: /* connect indication */
|
|
GET(T_CONN_IND, conn_ind);
|
|
ADDR(conn_ind, SRC);
|
|
ADDR(conn_ind, OPT);
|
|
tprintf(", SEQ=%ld", m.conn_ind.SEQ_number);
|
|
break;
|
|
#endif
|
|
#ifdef T_CONN_CON
|
|
case T_CONN_CON: /* connect corfirm */
|
|
GET(T_CONN_CON, conn_con);
|
|
ADDR(conn_con, RES);
|
|
ADDR(conn_con, OPT);
|
|
break;
|
|
#endif
|
|
#ifdef T_DISCON_IND
|
|
case T_DISCON_IND: /* discon indication */
|
|
GET(T_DISCON_IND, discon_ind);
|
|
COMMA();
|
|
tprintf("DISCON=%ld, SEQ=%ld",
|
|
m.discon_ind.DISCON_reason, m.discon_ind.SEQ_number);
|
|
break;
|
|
#endif
|
|
#ifdef T_DATA_IND
|
|
case T_DATA_IND: /* data indication */
|
|
GET(T_DATA_IND, data_ind);
|
|
COMMA();
|
|
tprintf("MORE=%ld", m.data_ind.MORE_flag);
|
|
break;
|
|
#endif
|
|
#ifdef T_EXDATA_IND
|
|
case T_EXDATA_IND: /* expedited data ind */
|
|
GET(T_EXDATA_IND, exdata_ind);
|
|
COMMA();
|
|
tprintf("MORE=%ld", m.exdata_ind.MORE_flag);
|
|
break;
|
|
#endif
|
|
#ifdef T_INFO_ACK
|
|
case T_INFO_ACK: /* info ack */
|
|
GET(T_INFO_ACK, info_ack);
|
|
COMMA();
|
|
tprintf("TSDU=%ld, ETSDU=%ld, CDATA=%ld, DDATA=%ld, "
|
|
"ADDR=%ld, OPT=%ld, TIDU=%ld, SERV=",
|
|
m.info_ack.TSDU_size, m.info_ack.ETSDU_size,
|
|
m.info_ack.CDATA_size, m.info_ack.DDATA_size,
|
|
m.info_ack.ADDR_size, m.info_ack.OPT_size,
|
|
m.info_ack.TIDU_size);
|
|
printxval(service_type, m.info_ack.SERV_type, "T_???");
|
|
tprintf(", CURRENT=");
|
|
printxval(ts_state, m.info_ack.CURRENT_state, "TS_???");
|
|
tprintf(", PROVIDER=");
|
|
printflags(provider_flags, m.info_ack.PROVIDER_flag, "???");
|
|
break;
|
|
#endif
|
|
#ifdef T_BIND_ACK
|
|
case T_BIND_ACK: /* bind ack */
|
|
GET(T_BIND_ACK, bind_ack);
|
|
ADDR(bind_ack, ADDR);
|
|
tprintf(", CONIND=%ld", m.bind_ack.CONIND_number);
|
|
break;
|
|
#endif
|
|
#ifdef T_ERROR_ACK
|
|
case T_ERROR_ACK: /* error ack */
|
|
GET(T_ERROR_ACK, error_ack);
|
|
COMMA();
|
|
tprintf("ERROR=");
|
|
printxval(transport_user_options,
|
|
m.error_ack.ERROR_prim, "TI_???");
|
|
tprintf(", TLI=");
|
|
printxval(tli_errors, m.error_ack.TLI_error, "T???");
|
|
tprintf("UNIX=%s", strerror(m.error_ack.UNIX_error));
|
|
break;
|
|
#endif
|
|
#ifdef T_OK_ACK
|
|
case T_OK_ACK: /* ok ack */
|
|
GET(T_OK_ACK, ok_ack);
|
|
COMMA();
|
|
tprintf("CORRECT=");
|
|
printxval(transport_user_options,
|
|
m.ok_ack.CORRECT_prim, "TI_???");
|
|
break;
|
|
#endif
|
|
#ifdef T_UNITDATA_IND
|
|
case T_UNITDATA_IND: /* unitdata ind */
|
|
GET(T_UNITDATA_IND, unitdata_ind);
|
|
ADDR(unitdata_ind, SRC);
|
|
ADDR(unitdata_ind, OPT);
|
|
break;
|
|
#endif
|
|
#ifdef T_UDERROR_IND
|
|
case T_UDERROR_IND: /* unitdata error ind */
|
|
GET(T_UDERROR_IND, uderror_ind);
|
|
ADDR(uderror_ind, DEST);
|
|
ADDR(uderror_ind, OPT);
|
|
tprintf(", ERROR=%ld", m.uderror_ind.ERROR_type);
|
|
break;
|
|
#endif
|
|
#ifdef T_OPTMGMT_ACK
|
|
case T_OPTMGMT_ACK: /* manage opt ack */
|
|
GET(T_OPTMGMT_ACK, optmgmt_ack);
|
|
COMMA();
|
|
tprintf("MGMT=");
|
|
printflags(transport_user_flags, m.optmgmt_ack.MGMT_flags,
|
|
"T_???");
|
|
STRUCT(optmgmt_ack, OPT, print_optmgmt);
|
|
break;
|
|
#endif
|
|
#ifdef T_ORDREL_IND
|
|
case T_ORDREL_IND: /* orderly rel ind */
|
|
GET(T_ORDREL_IND, ordrel_ind);
|
|
break;
|
|
#endif
|
|
#ifdef T_ADDR_REQ
|
|
case T_ADDR_REQ: /* address req */
|
|
GET(T_ADDR_REQ, addr_req);
|
|
break;
|
|
#endif
|
|
#ifdef T_ADDR_ACK
|
|
case T_ADDR_ACK: /* address response */
|
|
GET(T_ADDR_ACK, addr_ack);
|
|
ADDR(addr_ack, LOCADDR);
|
|
ADDR(addr_ack, REMADDR);
|
|
break;
|
|
#endif
|
|
default:
|
|
dump:
|
|
c = -1;
|
|
printstr(tcp, addr, len);
|
|
break;
|
|
}
|
|
|
|
if (c >= 0) tprintf("}");
|
|
|
|
#undef ADDR
|
|
#undef COMMA
|
|
#undef STRUCT
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
#endif /* TI_BIND */
|
|
|
|
|
|
static int internal_stream_ioctl(struct tcb *tcp, int arg)
|
|
{
|
|
struct strioctl si;
|
|
struct ioctlent *iop;
|
|
int in_and_out;
|
|
int timod = 0;
|
|
#ifdef SI_GETUDATA
|
|
struct si_udata udata;
|
|
#endif /* SI_GETUDATA */
|
|
|
|
if (!arg)
|
|
return 0;
|
|
if (umove(tcp, arg, &si) < 0) {
|
|
if (entering(tcp))
|
|
tprintf(", {...}");
|
|
return 1;
|
|
}
|
|
if (entering(tcp)) {
|
|
iop = ioctl_lookup(si.ic_cmd);
|
|
if (iop) {
|
|
tprintf(", {ic_cmd=%s", iop->symbol);
|
|
while ((iop = ioctl_next_match(iop)))
|
|
tprintf(" or %s", iop->symbol);
|
|
} else
|
|
tprintf(", {ic_cmd=%#x", si.ic_cmd);
|
|
if (si.ic_timout == INFTIM)
|
|
tprintf(", ic_timout=INFTIM, ");
|
|
else
|
|
tprintf(" ic_timout=%d, ", si.ic_timout);
|
|
}
|
|
in_and_out = 1;
|
|
switch (si.ic_cmd) {
|
|
#ifdef SI_GETUDATA
|
|
case SI_GETUDATA:
|
|
in_and_out = 0;
|
|
break;
|
|
#endif /* SI_GETUDATA */
|
|
}
|
|
if (in_and_out) {
|
|
if (entering(tcp))
|
|
tprintf("/* in */ ");
|
|
else
|
|
tprintf(", /* out */ ");
|
|
}
|
|
if (in_and_out || entering(tcp))
|
|
tprintf("ic_len=%d, ic_dp=", si.ic_len);
|
|
switch (si.ic_cmd) {
|
|
#ifdef TI_BIND
|
|
case TI_BIND:
|
|
/* in T_BIND_REQ, out T_BIND_ACK */
|
|
++timod;
|
|
if (entering(tcp)) {
|
|
print_transport_message(tcp,
|
|
T_BIND_REQ,
|
|
si.ic_dp, si.ic_len);
|
|
}
|
|
else {
|
|
print_transport_message(tcp,
|
|
T_BIND_ACK,
|
|
si.ic_dp, si.ic_len);
|
|
}
|
|
break;
|
|
#endif /* TI_BIND */
|
|
#ifdef TI_UNBIND
|
|
case TI_UNBIND:
|
|
/* in T_UNBIND_REQ, out T_OK_ACK */
|
|
++timod;
|
|
if (entering(tcp)) {
|
|
print_transport_message(tcp,
|
|
T_UNBIND_REQ,
|
|
si.ic_dp, si.ic_len);
|
|
}
|
|
else {
|
|
print_transport_message(tcp,
|
|
T_OK_ACK,
|
|
si.ic_dp, si.ic_len);
|
|
}
|
|
break;
|
|
#endif /* TI_UNBIND */
|
|
#ifdef TI_GETINFO
|
|
case TI_GETINFO:
|
|
/* in T_INFO_REQ, out T_INFO_ACK */
|
|
++timod;
|
|
if (entering(tcp)) {
|
|
print_transport_message(tcp,
|
|
T_INFO_REQ,
|
|
si.ic_dp, si.ic_len);
|
|
}
|
|
else {
|
|
print_transport_message(tcp,
|
|
T_INFO_ACK,
|
|
si.ic_dp, si.ic_len);
|
|
}
|
|
break;
|
|
#endif /* TI_GETINFO */
|
|
#ifdef TI_OPTMGMT
|
|
case TI_OPTMGMT:
|
|
/* in T_OPTMGMT_REQ, out T_OPTMGMT_ACK */
|
|
++timod;
|
|
if (entering(tcp)) {
|
|
print_transport_message(tcp,
|
|
T_OPTMGMT_REQ,
|
|
si.ic_dp, si.ic_len);
|
|
}
|
|
else {
|
|
print_transport_message(tcp,
|
|
T_OPTMGMT_ACK,
|
|
si.ic_dp, si.ic_len);
|
|
}
|
|
break;
|
|
#endif /* TI_OPTMGMT */
|
|
#ifdef SI_GETUDATA
|
|
case SI_GETUDATA:
|
|
if (entering(tcp))
|
|
break;
|
|
if (umove(tcp, (int) si.ic_dp, &udata) < 0)
|
|
tprintf("{...}");
|
|
else {
|
|
tprintf("{tidusize=%d, addrsize=%d, ",
|
|
udata.tidusize, udata.addrsize);
|
|
tprintf("optsize=%d, etsdusize=%d, ",
|
|
udata.optsize, udata.etsdusize);
|
|
tprintf("servtype=%d, so_state=%d, ",
|
|
udata.servtype, udata.so_state);
|
|
tprintf("so_options=%d", udata.so_options);
|
|
tprintf("}");
|
|
}
|
|
break;
|
|
#endif /* SI_GETUDATA */
|
|
default:
|
|
printstr(tcp, (long) si.ic_dp, si.ic_len);
|
|
break;
|
|
}
|
|
if (exiting(tcp)) {
|
|
tprintf("}");
|
|
if (timod && tcp->u_rval && !syserror(tcp)) {
|
|
tcp->auxstr = xlookup(tli_errors, tcp->u_rval);
|
|
return RVAL_STR + 1;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
stream_ioctl(struct tcb *tcp, int code, int arg)
|
|
{
|
|
#ifdef I_LIST
|
|
int i;
|
|
#endif
|
|
int val;
|
|
#ifdef I_FLUSHBAND
|
|
struct bandinfo bi;
|
|
#endif
|
|
struct strpeek sp;
|
|
struct strfdinsert sfi;
|
|
struct strrecvfd srf;
|
|
#ifdef I_LIST
|
|
struct str_list sl;
|
|
#endif
|
|
|
|
/* I_STR is a special case because the data is read & written. */
|
|
if (code == I_STR)
|
|
return internal_stream_ioctl(tcp, arg);
|
|
if (entering(tcp))
|
|
return 0;
|
|
|
|
switch (code) {
|
|
case I_PUSH:
|
|
case I_LOOK:
|
|
case I_FIND:
|
|
/* arg is a string */
|
|
tprintf(", ");
|
|
printpath(tcp, arg);
|
|
return 1;
|
|
case I_POP:
|
|
/* doesn't take an argument */
|
|
return 1;
|
|
case I_FLUSH:
|
|
/* argument is an option */
|
|
tprintf(", ");
|
|
printxval(stream_flush_options, arg, "FLUSH???");
|
|
return 1;
|
|
#ifdef I_FLUSHBAND
|
|
case I_FLUSHBAND:
|
|
/* argument is a pointer to a bandinfo struct */
|
|
if (umove(tcp, arg, &bi) < 0)
|
|
tprintf(", {...}");
|
|
else {
|
|
tprintf(", {bi_pri=%d, bi_flag=", bi.bi_pri);
|
|
printflags(stream_flush_options, bi.bi_flag, "FLUSH???");
|
|
tprintf("}");
|
|
}
|
|
return 1;
|
|
#endif /* I_FLUSHBAND */
|
|
case I_SETSIG:
|
|
/* argument is a set of flags */
|
|
tprintf(", ");
|
|
printflags(stream_setsig_flags, arg, "S_???");
|
|
return 1;
|
|
case I_GETSIG:
|
|
/* argument is a pointer to a set of flags */
|
|
if (syserror(tcp))
|
|
return 0;
|
|
tprintf(", [");
|
|
if (umove(tcp, arg, &val) < 0)
|
|
tprintf("?");
|
|
else
|
|
printflags(stream_setsig_flags, val, "S_???");
|
|
tprintf("]");
|
|
return 1;
|
|
case I_PEEK:
|
|
/* argument is a pointer to a strpeek structure */
|
|
if (syserror(tcp) || !arg)
|
|
return 0;
|
|
if (umove(tcp, arg, &sp) < 0) {
|
|
tprintf(", {...}");
|
|
return 1;
|
|
}
|
|
tprintf(", {ctlbuf=");
|
|
printstrbuf(tcp, &sp.ctlbuf, 1);
|
|
tprintf(", databuf=");
|
|
printstrbuf(tcp, &sp.databuf, 1);
|
|
tprintf(", flags=");
|
|
printflags(msgflags, sp.flags, "RS_???");
|
|
tprintf("}");
|
|
return 1;
|
|
case I_SRDOPT:
|
|
/* argument is an option with flags */
|
|
tprintf(", ");
|
|
printxval(stream_read_options, arg & RMODEMASK, "R???");
|
|
addflags(stream_read_flags, arg & ~RMODEMASK);
|
|
return 1;
|
|
case I_GRDOPT:
|
|
/* argument is an pointer to an option with flags */
|
|
if (syserror(tcp))
|
|
return 0;
|
|
tprintf(", [");
|
|
if (umove(tcp, arg, &val) < 0)
|
|
tprintf("?");
|
|
else {
|
|
printxval(stream_read_options,
|
|
arg & RMODEMASK, "R???");
|
|
addflags(stream_read_flags, arg & ~RMODEMASK);
|
|
}
|
|
tprintf("]");
|
|
return 1;
|
|
case I_NREAD:
|
|
#ifdef I_GETBAND
|
|
case I_GETBAND:
|
|
#endif
|
|
#ifdef I_SETCLTIME
|
|
case I_SETCLTIME:
|
|
#endif
|
|
#ifdef I_GETCLTIME
|
|
case I_GETCLTIME:
|
|
#endif
|
|
/* argument is a pointer to a decimal integer */
|
|
if (syserror(tcp))
|
|
return 0;
|
|
tprintf(", ");
|
|
printnum(tcp, arg, "%d");
|
|
return 1;
|
|
case I_FDINSERT:
|
|
/* argument is a pointer to a strfdinsert structure */
|
|
if (syserror(tcp) || !arg)
|
|
return 0;
|
|
if (umove(tcp, arg, &sfi) < 0) {
|
|
tprintf(", {...}");
|
|
return 1;
|
|
}
|
|
tprintf(", {ctlbuf=");
|
|
printstrbuf(tcp, &sfi.ctlbuf, 1);
|
|
tprintf(", databuf=");
|
|
printstrbuf(tcp, &sfi.databuf, 1);
|
|
tprintf(", flags=");
|
|
printflags(msgflags, sfi.flags, "RS_???");
|
|
tprintf(", filedes=%d, offset=%d}", sfi.fildes, sfi.offset);
|
|
return 1;
|
|
#ifdef I_SWROPT
|
|
case I_SWROPT:
|
|
/* argument is a set of flags */
|
|
tprintf(", ");
|
|
printflags(stream_write_flags, arg, "SND???");
|
|
return 1;
|
|
#endif /* I_SWROPT */
|
|
#ifdef I_GWROPT
|
|
case I_GWROPT:
|
|
/* argument is an pointer to an option with flags */
|
|
if (syserror(tcp))
|
|
return 0;
|
|
tprintf(", [");
|
|
if (umove(tcp, arg, &val) < 0)
|
|
tprintf("?");
|
|
else
|
|
printflags(stream_write_flags, arg, "SND???");
|
|
tprintf("]");
|
|
return 1;
|
|
#endif /* I_GWROPT */
|
|
case I_SENDFD:
|
|
#ifdef I_CKBAND
|
|
case I_CKBAND:
|
|
#endif
|
|
#ifdef I_CANPUT
|
|
case I_CANPUT:
|
|
#endif
|
|
case I_LINK:
|
|
case I_UNLINK:
|
|
case I_PLINK:
|
|
case I_PUNLINK:
|
|
/* argument is a decimal integer */
|
|
tprintf(", %d", arg);
|
|
return 1;
|
|
case I_RECVFD:
|
|
/* argument is a pointer to a strrecvfd structure */
|
|
if (syserror(tcp) || !arg)
|
|
return 0;
|
|
if (umove(tcp, arg, &srf) < 0) {
|
|
tprintf(", {...}");
|
|
return 1;
|
|
}
|
|
tprintf(", {fd=%d, uid=%lu, gid=%lu}", srf.fd,
|
|
(unsigned long) srf.uid, (unsigned long) srf.gid);
|
|
return 1;
|
|
#ifdef I_LIST
|
|
case I_LIST:
|
|
if (syserror(tcp))
|
|
return 0;
|
|
if (arg == 0) {
|
|
tprintf(", NULL");
|
|
return 1;
|
|
}
|
|
if (umove(tcp, arg, &sl) < 0) {
|
|
tprintf(", {...}");
|
|
return 1;
|
|
}
|
|
tprintf(", {sl_nmods=%d, sl_modlist=[", sl.sl_nmods);
|
|
for (i = 0; i < tcp->u_rval; i++) {
|
|
if (i)
|
|
tprintf(", ");
|
|
printpath(tcp, (int) sl.sl_modlist[i].l_name);
|
|
}
|
|
tprintf("]}");
|
|
return 1;
|
|
#endif /* I_LIST */
|
|
#ifdef I_ATMARK
|
|
case I_ATMARK:
|
|
tprintf(", ");
|
|
printxval(stream_atmark_options, arg, "???MARK");
|
|
return 1;
|
|
#endif /* I_ATMARK */
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
#endif /* !LINUX && !FREEBSD */
|
|
|
|
#endif /* HAVE_SYS_STREAM_H || LINUX || FREEBSD */
|