blob: cb64154f41348a280fdb83b31345ef680eff2251 [file] [log] [blame]
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#define _SYSCALL32
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <libproc.h>
#include <string.h>
#include <limits.h>
#include <sys/statfs.h>
#include <sys/times.h>
#include <sys/timex.h>
#include <sys/utssys.h>
#include <sys/utsname.h>
#include <sys/ipc.h>
#include <sys/ipc_impl.h>
#include <sys/msg.h>
#include <sys/msg_impl.h>
#include <sys/sem.h>
#include <sys/sem_impl.h>
#include <sys/shm.h>
#include <sys/shm_impl.h>
#include <sys/dirent.h>
#include <sys/utime.h>
#include <ustat.h>
#include <fcntl.h>
#include <time.h>
#include <sys/termios.h>
#include <sys/termiox.h>
#include <sys/termio.h>
#include <sys/ttold.h>
#include <sys/jioctl.h>
#include <sys/filio.h>
#include <stropts.h>
#include <poll.h>
#include <sys/uio.h>
#include <sys/resource.h>
#include <sys/statvfs.h>
#include <sys/time.h>
#include <sys/aio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <sys/byteorder.h>
#include <arpa/inet.h>
#include <sys/audioio.h>
#include <sys/cladm.h>
#include <sys/synch.h>
#include <sys/synch32.h>
#include <sys/sysmacros.h>
#include <sys/sendfile.h>
#include <priv.h>
#include <ucred.h>
#include <sys/ucred.h>
#include <sys/port_impl.h>
#include <sys/zone.h>
#include <sys/priv_impl.h>
#include <sys/priv.h>
#include <tsol/label.h>
#include "ramdata.h"
#include "systable.h"
#include "proto.h"
void show_sigset(private_t *, long, const char *);
void show_ioctl(private_t *, int, long);
void
prtime(private_t *pri, const char *name, time_t value)
{
char str[80];
(void) strftime(str, sizeof (str), "%b %e %H:%M:%S %Z %Y",
localtime(&value));
(void) printf("%s\t%s%s [ %llu ]\n",
pri->pname,
name,
str,
(longlong_t)value);
}
void
prtimestruc(private_t *pri, const char *name, timestruc_t *value)
{
prtime(pri, name, value->tv_sec);
}
void
show_utime(private_t *pri)
{
long offset;
struct utimbuf utimbuf;
if (pri->sys_nargs < 2 || (offset = pri->sys_args[1]) == NULL)
return;
if (data_model == PR_MODEL_NATIVE) {
if (Pread(Proc, &utimbuf, sizeof (utimbuf), offset)
!= sizeof (utimbuf))
return;
} else {
struct utimbuf32 utimbuf32;
if (Pread(Proc, &utimbuf32, sizeof (utimbuf32), offset)
!= sizeof (utimbuf32))
return;
utimbuf.actime = (time_t)utimbuf32.actime;
utimbuf.modtime = (time_t)utimbuf32.modtime;
}
/* print access and modification times */
prtime(pri, "atime: ", utimbuf.actime);
prtime(pri, "mtime: ", utimbuf.modtime);
}
void
show_utimes(private_t *pri)
{
long offset;
struct {
struct timeval atime;
struct timeval mtime;
} utimbuf;
if (pri->sys_nargs < 2 || (offset = pri->sys_args[1]) == NULL)
return;
if (data_model == PR_MODEL_NATIVE) {
if (Pread(Proc, &utimbuf, sizeof (utimbuf), offset)
!= sizeof (utimbuf))
return;
} else {
struct {
struct timeval32 atime;
struct timeval32 mtime;
} utimbuf32;
if (Pread(Proc, &utimbuf32, sizeof (utimbuf32), offset)
!= sizeof (utimbuf32))
return;
TIMEVAL32_TO_TIMEVAL(&utimbuf.atime, &utimbuf32.atime);
TIMEVAL32_TO_TIMEVAL(&utimbuf.mtime, &utimbuf32.mtime);
}
/* print access and modification times */
prtime(pri, "atime: ", utimbuf.atime.tv_sec);
prtime(pri, "mtime: ", utimbuf.mtime.tv_sec);
}
void
show_timeofday(private_t *pri)
{
struct timeval tod;
long offset;
if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL)
return;
if (data_model == PR_MODEL_NATIVE) {
if (Pread(Proc, &tod, sizeof (tod), offset)
!= sizeof (tod))
return;
} else {
struct timeval32 tod32;
if (Pread(Proc, &tod32, sizeof (tod32), offset)
!= sizeof (tod32))
return;
TIMEVAL32_TO_TIMEVAL(&tod, &tod32);
}
prtime(pri, "time: ", tod.tv_sec);
}
void
show_itimerval(private_t *pri, long offset, const char *name)
{
struct itimerval itimerval;
if (offset == NULL)
return;
if (data_model == PR_MODEL_NATIVE) {
if (Pread(Proc, &itimerval, sizeof (itimerval), offset)
!= sizeof (itimerval))
return;
} else {
struct itimerval32 itimerval32;
if (Pread(Proc, &itimerval32, sizeof (itimerval32), offset)
!= sizeof (itimerval32))
return;
ITIMERVAL32_TO_ITIMERVAL(&itimerval, &itimerval32);
}
(void) printf(
"%s\t%s: interval: %4ld.%6.6ld sec value: %4ld.%6.6ld sec\n",
pri->pname,
name,
itimerval.it_interval.tv_sec,
itimerval.it_interval.tv_usec,
itimerval.it_value.tv_sec,
itimerval.it_value.tv_usec);
}
void
show_timeval(private_t *pri, long offset, const char *name)
{
struct timeval timeval;
if (offset == NULL)
return;
if (data_model == PR_MODEL_NATIVE) {
if (Pread(Proc, &timeval, sizeof (timeval), offset)
!= sizeof (timeval))
return;
} else {
struct timeval32 timeval32;
if (Pread(Proc, &timeval32, sizeof (timeval32), offset)
!= sizeof (timeval32))
return;
TIMEVAL32_TO_TIMEVAL(&timeval, &timeval32);
}
(void) printf(
"%s\t%s: %ld.%6.6ld sec\n",
pri->pname,
name,
timeval.tv_sec,
timeval.tv_usec);
}
void
show_timestruc(private_t *pri, long offset, const char *name)
{
timestruc_t timestruc;
if (offset == NULL)
return;
if (data_model == PR_MODEL_NATIVE) {
if (Pread(Proc, &timestruc, sizeof (timestruc), offset)
!= sizeof (timestruc))
return;
} else {
timestruc32_t timestruc32;
if (Pread(Proc, &timestruc32, sizeof (timestruc32), offset)
!= sizeof (timestruc32))
return;
TIMESPEC32_TO_TIMESPEC(&timestruc, &timestruc32);
}
(void) printf(
"%s\t%s: %ld.%9.9ld sec\n",
pri->pname,
name,
timestruc.tv_sec,
timestruc.tv_nsec);
}
void
show_stime(private_t *pri)
{
if (pri->sys_nargs >= 1) {
/* print new system time */
prtime(pri, "systime = ", (time_t)pri->sys_args[0]);
}
}
void
show_times(private_t *pri)
{
long hz = sysconf(_SC_CLK_TCK);
long offset;
struct tms tms;
if (pri->sys_nargs < 1 || (offset = pri->sys_args[0]) == NULL)
return;
if (data_model == PR_MODEL_NATIVE) {
if (Pread(Proc, &tms, sizeof (tms), offset)
!= sizeof (tms))
return;
} else {
struct tms32 tms32;
if (Pread(Proc, &tms32, sizeof (tms32), offset)
!= sizeof (tms32))
return;
/*
* This looks a bit odd (since the values are actually
* signed), but we need to suppress sign extension to
* preserve compatibility (we've always printed these
* numbers as unsigned quantities).
*/
tms.tms_utime = (unsigned)tms32.tms_utime;
tms.tms_stime = (unsigned)tms32.tms_stime;
tms.tms_cutime = (unsigned)tms32.tms_cutime;
tms.tms_cstime = (unsigned)tms32.tms_cstime;
}
(void) printf(
"%s\tutim=%-6lu stim=%-6lu cutim=%-6lu cstim=%-6lu (HZ=%ld)\n",
pri->pname,
tms.tms_utime,
tms.tms_stime,
tms.tms_cutime,
tms.tms_cstime,
hz);
}
void
show_uname(private_t *pri, long offset)
{
/*
* Old utsname buffer (no longer accessible in <sys/utsname.h>).
*/
struct {
char sysname[9];
char nodename[9];
char release[9];
char version[9];
char machine[9];
} ubuf;
if (offset != NULL &&
Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) {
(void) printf(
"%s\tsys=%-9.9snod=%-9.9srel=%-9.9sver=%-9.9smch=%.9s\n",
pri->pname,
ubuf.sysname,
ubuf.nodename,
ubuf.release,
ubuf.version,
ubuf.machine);
}
}
/* XX64 -- definition of 'struct ustat' is strange -- check out the defn */
void
show_ustat(private_t *pri, long offset)
{
struct ustat ubuf;
if (offset != NULL &&
Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) {
(void) printf(
"%s\ttfree=%-6ld tinode=%-5lu fname=%-6.6s fpack=%-.6s\n",
pri->pname,
ubuf.f_tfree,
ubuf.f_tinode,
ubuf.f_fname,
ubuf.f_fpack);
}
}
#ifdef _LP64
void
show_ustat32(private_t *pri, long offset)
{
struct ustat32 ubuf;
if (offset != NULL &&
Pread(Proc, &ubuf, sizeof (ubuf), offset) == sizeof (ubuf)) {
(void) printf(
"%s\ttfree=%-6d tinode=%-5u fname=%-6.6s fpack=%-.6s\n",
pri->pname,
ubuf.f_tfree,
ubuf.f_tinode,
ubuf.f_fname,
ubuf.f_fpack);
}
}
#endif /* _LP64 */
void
show_fusers(private_t *pri, long offset, long nproc)
{
f_user_t fubuf;
int serial = (nproc > 4);
if (offset == NULL)
return;
/* enter region of lengthy output */
if (serial)
Eserialize();
while (nproc > 0 &&
Pread(Proc, &fubuf, sizeof (fubuf), offset) == sizeof (fubuf)) {
(void) printf("%s\tpid=%-5d uid=%-5d flags=%s\n",
pri->pname,
(int)fubuf.fu_pid,
(int)fubuf.fu_uid,
fuflags(pri, fubuf.fu_flags));
nproc--;
offset += sizeof (fubuf);
}
/* exit region of lengthy output */
if (serial)
Xserialize();
}
void
show_utssys(private_t *pri, long r0)
{
if (pri->sys_nargs >= 3) {
switch (pri->sys_args[2]) {
case UTS_UNAME:
show_uname(pri, (long)pri->sys_args[0]);
break;
case UTS_USTAT:
show_ustat(pri, (long)pri->sys_args[0]);
break;
case UTS_FUSERS:
show_fusers(pri, (long)pri->sys_args[3], r0);
break;
}
}
}
#ifdef _LP64
void
show_utssys32(private_t *pri, long r0)
{
if (pri->sys_nargs >= 3) {
switch (pri->sys_args[2]) {
case UTS_UNAME:
show_uname(pri, (long)pri->sys_args[0]);
break;
case UTS_USTAT:
show_ustat32(pri, (long)pri->sys_args[0]);
break;
case UTS_FUSERS:
show_fusers(pri, (long)pri->sys_args[3], r0);
break;
}
}
}
#endif /* _LP64 */
void
show_cladm(private_t *pri, int code, int function, long offset)
{
int arg;
switch (code) {
case CL_INITIALIZE:
switch (function) {
case CL_GET_BOOTFLAG:
if (Pread(Proc, &arg, sizeof (arg), offset)
== sizeof (arg)) {
if (arg & CLUSTER_CONFIGURED)
(void) printf("%s\tbootflags="
"CLUSTER_CONFIGURED", pri->pname);
if (arg & CLUSTER_BOOTED)
(void) printf("|CLUSTER_BOOTED\n");
}
break;
}
break;
case CL_CONFIG:
switch (function) {
case CL_NODEID:
case CL_HIGHEST_NODEID:
if (Pread(Proc, &arg, sizeof (arg), offset)
== sizeof (arg))
(void) printf("%s\tnodeid=%d\n",
pri->pname, arg);
}
break;
}
}
#define ALL_LOCK_TYPES \
(USYNC_PROCESS|LOCK_ERRORCHECK|LOCK_RECURSIVE|USYNC_PROCESS_ROBUST|\
LOCK_PRIO_INHERIT|LOCK_PRIO_PROTECT|LOCK_ROBUST_NP)
/* return cv and mutex types */
const char *
synch_type(private_t *pri, uint_t type)
{
char *str = pri->code_buf;
if (type & USYNC_PROCESS)
(void) strcpy(str, "USYNC_PROCESS");
else
(void) strcpy(str, "USYNC_THREAD");
if (type & LOCK_ERRORCHECK)
(void) strcat(str, "|LOCK_ERRORCHECK");
if (type & LOCK_RECURSIVE)
(void) strcat(str, "|LOCK_RECURSIVE");
if (type & USYNC_PROCESS_ROBUST)
(void) strcat(str, "|USYNC_PROCESS_ROBUST");
if (type & LOCK_PRIO_INHERIT)
(void) strcat(str, "|LOCK_PRIO_INHERIT");
if (type & LOCK_PRIO_PROTECT)
(void) strcat(str, "|LOCK_PRIO_PROTECT");
if (type & LOCK_ROBUST_NP)
(void) strcat(str, "|LOCK_ROBUST_NP");
if ((type &= ~ALL_LOCK_TYPES) != 0)
(void) sprintf(str + strlen(str), "|0x%.4X", type);
return ((const char *)str);
}
void
show_mutex(private_t *pri, long offset)
{
lwp_mutex_t mutex;
if (Pread(Proc, &mutex, sizeof (mutex), offset) == sizeof (mutex)) {
(void) printf("%s\tmutex type: %s\n",
pri->pname,
synch_type(pri, mutex.mutex_type));
}
}
void
show_condvar(private_t *pri, long offset)
{
lwp_cond_t condvar;
if (Pread(Proc, &condvar, sizeof (condvar), offset)
== sizeof (condvar)) {
(void) printf("%s\tcondvar type: %s\n",
pri->pname,
synch_type(pri, condvar.cond_type));
}
}
void
show_sema(private_t *pri, long offset)
{
lwp_sema_t sema;
if (Pread(Proc, &sema, sizeof (sema), offset) == sizeof (sema)) {
(void) printf("%s\tsema type: %s count = %u\n",
pri->pname,
synch_type(pri, sema.sema_type),
sema.sema_count);
}
}
void
show_rwlock(private_t *pri, long offset)
{
lwp_rwlock_t rwlock;
if (Pread(Proc, &rwlock, sizeof (rwlock), offset) == sizeof (rwlock)) {
(void) printf("%s\trwlock type: %s readers = %d\n",
pri->pname,
synch_type(pri, rwlock.rwlock_type),
rwlock.rwlock_readers);
}
}
/* represent character as itself ('c') or octal (012) */
char *
show_char(char *buf, int c)
{
const char *fmt;
if (c >= ' ' && c < 0177)
fmt = "'%c'";
else
fmt = "%.3o";
(void) sprintf(buf, fmt, c&0xff);
return (buf);
}
void
show_termio(private_t *pri, long offset)
{
struct termio termio;
char cbuf[8];
int i;
if (Pread(Proc, &termio, sizeof (termio), offset) == sizeof (termio)) {
(void) printf(
"%s\tiflag=0%.6o oflag=0%.6o cflag=0%.6o lflag=0%.6o line=%d\n",
pri->pname,
termio.c_iflag,
termio.c_oflag,
termio.c_cflag,
termio.c_lflag,
termio.c_line);
(void) printf("%s\t cc: ", pri->pname);
for (i = 0; i < NCC; i++)
(void) printf(" %s",
show_char(cbuf, (int)termio.c_cc[i]));
(void) fputc('\n', stdout);
}
}
void
show_termios(private_t *pri, long offset)
{
struct termios termios;
char cbuf[8];
int i;
if (Pread(Proc, &termios, sizeof (termios), offset)
== sizeof (termios)) {
(void) printf(
"%s\tiflag=0%.6o oflag=0%.6o cflag=0%.6o lflag=0%.6o\n",
pri->pname,
termios.c_iflag,
termios.c_oflag,
termios.c_cflag,
termios.c_lflag);
(void) printf("%s\t cc: ", pri->pname);
for (i = 0; i < NCCS; i++) {
if (i == NCC) /* show new chars on new line */
(void) printf("\n%s\t\t", pri->pname);
(void) printf(" %s",
show_char(cbuf, (int)termios.c_cc[i]));
}
(void) fputc('\n', stdout);
}
}
void
show_termiox(private_t *pri, long offset)
{
struct termiox termiox;
int i;
if (Pread(Proc, &termiox, sizeof (termiox), offset)
== sizeof (termiox)) {
(void) printf("%s\thflag=0%.3o cflag=0%.3o rflag=0%.3o",
pri->pname,
termiox.x_hflag,
termiox.x_cflag,
termiox.x_rflag[0]);
for (i = 1; i < NFF; i++)
(void) printf(",0%.3o", termiox.x_rflag[i]);
(void) printf(" sflag=0%.3o\n",
termiox.x_sflag);
}
}
void
show_sgttyb(private_t *pri, long offset)
{
struct sgttyb sgttyb;
if (Pread(Proc, &sgttyb, sizeof (sgttyb), offset) == sizeof (sgttyb)) {
char erase[8];
char kill[8];
(void) printf(
"%s\tispeed=%-2d ospeed=%-2d erase=%s kill=%s flags=0x%.8x\n",
pri->pname,
sgttyb.sg_ispeed&0xff,
sgttyb.sg_ospeed&0xff,
show_char(erase, sgttyb.sg_erase),
show_char(kill, sgttyb.sg_kill),
sgttyb.sg_flags);
}
}
void
show_ltchars(private_t *pri, long offset)
{
struct ltchars ltchars;
char *p;
char cbuf[8];
int i;
if (Pread(Proc, &ltchars, sizeof (ltchars), offset)
== sizeof (ltchars)) {
(void) printf("%s\t cc: ", pri->pname);
for (p = (char *)&ltchars, i = 0; i < sizeof (ltchars); i++)
(void) printf(" %s", show_char(cbuf, (int)*p++));
(void) fputc('\n', stdout);
}
}
void
show_tchars(private_t *pri, long offset)
{
struct tchars tchars;
char *p;
char cbuf[8];
int i;
if (Pread(Proc, &tchars, sizeof (tchars), offset) == sizeof (tchars)) {
(void) printf("%s\t cc: ", pri->pname);
for (p = (char *)&tchars, i = 0; i < sizeof (tchars); i++)
(void) printf(" %s", show_char(cbuf, (int)*p++));
(void) fputc('\n', stdout);
}
}
void
show_termcb(private_t *pri, long offset)
{
struct termcb termcb;
if (Pread(Proc, &termcb, sizeof (termcb), offset) == sizeof (termcb)) {
(void) printf(
"%s\tflgs=0%.2o termt=%d crow=%d ccol=%d vrow=%d lrow=%d\n",
pri->pname,
termcb.st_flgs&0xff,
termcb.st_termt&0xff,
termcb.st_crow&0xff,
termcb.st_ccol&0xff,
termcb.st_vrow&0xff,
termcb.st_lrow&0xff);
}
}
/* integer value pointed to by ioctl() arg */
void
show_strint(private_t *pri, int code, long offset)
{
int val;
if (Pread(Proc, &val, sizeof (val), offset) == sizeof (val)) {
const char *s = NULL;
switch (code) { /* interpret these symbolically */
case I_GRDOPT:
s = strrdopt(val);
break;
case I_GETSIG:
s = strevents(pri, val);
break;
case TIOCFLUSH:
s = tiocflush(pri, val);
break;
}
if (s == NULL)
(void) printf("%s\t0x%.8lX: %d\n",
pri->pname, offset, val);
else
(void) printf("%s\t0x%.8lX: %s\n",
pri->pname, offset, s);
}
}
void
show_strioctl(private_t *pri, long offset)
{
struct strioctl strioctl;
if (Pread(Proc, &strioctl, sizeof (strioctl), offset) ==
sizeof (strioctl)) {
(void) printf(
"%s\tcmd=%s timout=%d len=%d dp=0x%.8lX\n",
pri->pname,
ioctlname(pri, strioctl.ic_cmd),
strioctl.ic_timout,
strioctl.ic_len,
(long)strioctl.ic_dp);
if (pri->recur++ == 0) /* avoid indefinite recursion */
show_ioctl(pri, strioctl.ic_cmd,
(long)strioctl.ic_dp);
--pri->recur;
}
}
#ifdef _LP64
void
show_strioctl32(private_t *pri, long offset)
{
struct strioctl32 strioctl;
if (Pread(Proc, &strioctl, sizeof (strioctl), offset) ==
sizeof (strioctl)) {
(void) printf(
"%s\tcmd=%s timout=%d len=%d dp=0x%.8lX\n",
pri->pname,
ioctlname(pri, strioctl.ic_cmd),
strioctl.ic_timout,
strioctl.ic_len,
(long)strioctl.ic_dp);
if (pri->recur++ == 0) /* avoid indefinite recursion */
show_ioctl(pri, strioctl.ic_cmd,
(long)strioctl.ic_dp);
--pri->recur;
}
}
#endif /* _LP64 */
void
print_strbuf(private_t *pri, struct strbuf *sp, const char *name, int dump)
{
(void) printf(
"%s\t%s: maxlen=%-4d len=%-4d buf=0x%.8lX",
pri->pname,
name,
sp->maxlen,
sp->len,
(long)sp->buf);
/*
* Should we show the buffer contents?
* Keyed to the '-r fds' and '-w fds' options?
*/
if (sp->buf == NULL || sp->len <= 0)
(void) fputc('\n', stdout);
else {
int nb = (sp->len > 8)? 8 : sp->len;
char buffer[8];
char obuf[40];
if (Pread(Proc, buffer, (size_t)nb, (long)sp->buf) == nb) {
(void) strcpy(obuf, ": \"");
showbytes(buffer, nb, obuf+3);
(void) strcat(obuf,
(nb == sp->len)?
(const char *)"\"" : (const char *)"\"..");
(void) fputs(obuf, stdout);
}
(void) fputc('\n', stdout);
if (dump && sp->len > 8)
showbuffer(pri, (long)sp->buf, (long)sp->len);
}
}
#ifdef _LP64
void
print_strbuf32(private_t *pri, struct strbuf32 *sp, const char *name, int dump)
{
(void) printf(
"%s\t%s: maxlen=%-4d len=%-4d buf=0x%.8lX",
pri->pname,
name,
sp->maxlen,
sp->len,
(long)sp->buf);
/*
* Should we show the buffer contents?
* Keyed to the '-r fds' and '-w fds' options?
*/
if (sp->buf == NULL || sp->len <= 0)
(void) fputc('\n', stdout);
else {
int nb = (sp->len > 8)? 8 : sp->len;
char buffer[8];
char obuf[40];
if (Pread(Proc, buffer, (size_t)nb, (long)sp->buf) == nb) {
(void) strcpy(obuf, ": \"");
showbytes(buffer, nb, obuf+3);
(void) strcat(obuf,
(nb == sp->len)?
(const char *)"\"" : (const char *)"\"..");
(void) fputs(obuf, stdout);
}
(void) fputc('\n', stdout);
if (dump && sp->len > 8)
showbuffer(pri, (long)sp->buf, (long)sp->len);
}
}
#endif /* _LP64 */
/* strpeek and strfdinsert flags word */
const char *
strflags(private_t *pri, int flags)
{
const char *s;
switch (flags) {
case 0:
s = "0";
break;
case RS_HIPRI:
s = "RS_HIPRI";
break;
default:
(void) sprintf(pri->code_buf, "0x%.4X", flags);
s = pri->code_buf;
}
return (s);
}
void
show_strpeek(private_t *pri, long offset)
{
struct strpeek strpeek;
if (Pread(Proc, &strpeek, sizeof (strpeek), offset)
== sizeof (strpeek)) {
print_strbuf(pri, &strpeek.ctlbuf, "ctl", FALSE);
print_strbuf(pri, &strpeek.databuf, "dat", FALSE);
(void) printf("%s\tflags=%s\n",
pri->pname,
strflags(pri, strpeek.flags));
}
}
#ifdef _LP64
void
show_strpeek32(private_t *pri, long offset)
{
struct strpeek32 strpeek;
if (Pread(Proc, &strpeek, sizeof (strpeek), offset)
== sizeof (strpeek)) {
print_strbuf32(pri, &strpeek.ctlbuf, "ctl", FALSE);
print_strbuf32(pri, &strpeek.databuf, "dat", FALSE);
(void) printf("%s\tflags=%s\n",
pri->pname,
strflags(pri, strpeek.flags));
}
}
#endif /* _LP64 */
void
show_strfdinsert(private_t *pri, long offset)
{
struct strfdinsert strfdinsert;
if (Pread(Proc, &strfdinsert, sizeof (strfdinsert), offset) ==
sizeof (strfdinsert)) {
print_strbuf(pri, &strfdinsert.ctlbuf, "ctl", FALSE);
print_strbuf(pri, &strfdinsert.databuf, "dat", FALSE);
(void) printf("%s\tflags=%s fildes=%d offset=%d\n",
pri->pname,
strflags(pri, strfdinsert.flags),
strfdinsert.fildes,
strfdinsert.offset);
}
}
#ifdef _LP64
void
show_strfdinsert32(private_t *pri, long offset)
{
struct strfdinsert32 strfdinsert;
if (Pread(Proc, &strfdinsert, sizeof (strfdinsert), offset) ==
sizeof (strfdinsert)) {
print_strbuf32(pri, &strfdinsert.ctlbuf, "ctl", FALSE);
print_strbuf32(pri, &strfdinsert.databuf, "dat", FALSE);
(void) printf("%s\tflags=%s fildes=%d offset=%d\n",
pri->pname,
strflags(pri, strfdinsert.flags),
strfdinsert.fildes,
strfdinsert.offset);
}
}
#endif /* _LP64 */
void
show_strrecvfd(private_t *pri, long offset)
{
struct strrecvfd strrecvfd;
if (Pread(Proc, &strrecvfd, sizeof (strrecvfd), offset) ==
sizeof (strrecvfd)) {
(void) printf(
"%s\tfd=%-5d uid=%-5d gid=%d\n",
pri->pname,
strrecvfd.fd,
(int)strrecvfd.uid,
(int)strrecvfd.gid);
}
}
void
show_strlist(private_t *pri, long offset)
{
struct str_list strlist;
struct str_mlist list;
int count;
if (Pread(Proc, &strlist, sizeof (strlist), offset) ==
sizeof (strlist)) {
(void) printf("%s\tnmods=%d modlist=0x%.8lX\n",
pri->pname,
strlist.sl_nmods,
(long)strlist.sl_modlist);
count = strlist.sl_nmods;
offset = (long)strlist.sl_modlist;
while (!interrupt && --count >= 0) {
if (Pread(Proc, &list, sizeof (list), offset) !=
sizeof (list))
break;
(void) printf("%s\t\t\"%.*s\"\n",
pri->pname,
(int)sizeof (list.l_name),
list.l_name);
offset += sizeof (struct str_mlist);
}
}
}
#ifdef _LP64
void
show_strlist32(private_t *pri, long offset)
{
struct str_list32 strlist;
struct str_mlist list;
int count;
if (Pread(Proc, &strlist, sizeof (strlist), offset) ==
sizeof (strlist)) {
(void) printf("%s\tnmods=%d modlist=0x%.8lX\n",
pri->pname,
strlist.sl_nmods,
(long)strlist.sl_modlist);
count = strlist.sl_nmods;
offset = (long)strlist.sl_modlist;
while (!interrupt && --count >= 0) {
if (Pread(Proc, &list, sizeof (list), offset) !=
sizeof (list))
break;
(void) printf("%s\t\t\"%.*s\"\n",
pri->pname,
(int)sizeof (list.l_name),
list.l_name);
offset += sizeof (struct str_mlist);
}
}
}
#endif /* _LP64 */
void
show_jwinsize(private_t *pri, long offset)
{
struct jwinsize jwinsize;
if (Pread(Proc, &jwinsize, sizeof (jwinsize), offset) ==
sizeof (jwinsize)) {
(void) printf(
"%s\tbytesx=%-3u bytesy=%-3u bitsx=%-3u bitsy=%-3u\n",
pri->pname,
(unsigned)jwinsize.bytesx,
(unsigned)jwinsize.bytesy,
(unsigned)jwinsize.bitsx,
(unsigned)jwinsize.bitsy);
}
}
void
show_winsize(private_t *pri, long offset)
{
struct winsize winsize;
if (Pread(Proc, &winsize, sizeof (winsize), offset)
== sizeof (winsize)) {
(void) printf(
"%s\trow=%-3d col=%-3d xpixel=%-3d ypixel=%-3d\n",
pri->pname,
winsize.ws_row,
winsize.ws_col,
winsize.ws_xpixel,
winsize.ws_ypixel);
}
}
struct audio_stuff {
uint_t bit;
const char *str;
};
const struct audio_stuff audio_output_ports[] = {
{ AUDIO_SPEAKER, "SPEAKER" },
{ AUDIO_HEADPHONE, "HEADPHONE" },
{ AUDIO_LINE_OUT, "LINE_OUT" },
{ AUDIO_SPDIF_OUT, "SPDIF_OUT" },
{ AUDIO_AUX1_OUT, "AUX1_OUT" },
{ AUDIO_AUX2_OUT, "AUX2_OUT" },
{ 0, NULL }
};
const struct audio_stuff audio_input_ports[] = {
{ AUDIO_MICROPHONE, "MICROPHONE" },
{ AUDIO_LINE_IN, "LINE_IN" },
{ AUDIO_CD, "CD" },
{ AUDIO_SPDIF_IN, "SPDIF_IN" },
{ AUDIO_AUX1_IN, "AUX1_IN" },
{ AUDIO_AUX2_IN, "AUX2_IN" },
{ AUDIO_CODEC_LOOPB_IN, "CODEC_LOOPB_IN" },
{ AUDIO_SUNVTS, "SUNVTS" },
{ 0, NULL }
};
static const struct audio_stuff audio_hw_features[] = {
{ AUDIO_HWFEATURE_DUPLEX, "DUPLEX" },
{ AUDIO_HWFEATURE_MSCODEC, "MSCODEC" },
{ AUDIO_HWFEATURE_IN2OUT, "IN2OUT" },
{ AUDIO_HWFEATURE_PLAY, "PLAY" },
{ AUDIO_HWFEATURE_RECORD, "RECORD" },
{ 0, NULL }
};
static const struct audio_stuff audio_sw_features[] = {
{ AUDIO_SWFEATURE_MIXER, "MIXER" },
{ 0, NULL }
};
void
show_audio_features(const private_t *pri,
const struct audio_stuff *audio_porttab, uint_t features,
const char *name)
{
(void) printf("%s\t%s=", pri->pname, name);
if (features == 0) {
(void) printf("0\n");
return;
}
for (; audio_porttab->bit != 0; ++audio_porttab) {
if (features & audio_porttab->bit) {
(void) printf(audio_porttab->str);
features &= ~audio_porttab->bit;
if (features)
(void) putchar('|');
}
}
if (features)
(void) printf("0x%x", features);
(void) putchar('\n');
}
void
show_audio_ports(private_t *pri, const char *mode,
const char *field, uint_t ports)
{
const struct audio_stuff *audio_porttab;
(void) printf("%s\t%s\t%s=", pri->pname, mode, field);
if (ports == 0) {
(void) printf("0\n");
return;
}
if (*mode == 'p')
audio_porttab = audio_output_ports;
else
audio_porttab = audio_input_ports;
for (; audio_porttab->bit != 0; ++audio_porttab) {
if (ports & audio_porttab->bit) {
(void) printf(audio_porttab->str);
ports &= ~audio_porttab->bit;
if (ports)
(void) putchar('|');
}
}
if (ports)
(void) printf("0x%x", ports);
(void) putchar('\n');
}
void
show_audio_prinfo(private_t *pri, const char *mode, struct audio_prinfo *au_pr)
{
const char *s;
/*
* The following values describe the audio data encoding.
*/
(void) printf("%s\t%s\tsample_rate=%u channels=%u precision=%u\n",
pri->pname, mode,
au_pr->sample_rate,
au_pr->channels,
au_pr->precision);
s = NULL;
switch (au_pr->encoding) {
case AUDIO_ENCODING_NONE: s = "NONE"; break;
case AUDIO_ENCODING_ULAW: s = "ULAW"; break;
case AUDIO_ENCODING_ALAW: s = "ALAW"; break;
case AUDIO_ENCODING_LINEAR: s = "LINEAR"; break;
case AUDIO_ENCODING_DVI: s = "DVI"; break;
case AUDIO_ENCODING_LINEAR8: s = "LINEAR8"; break;
}
if (s)
(void) printf("%s\t%s\tencoding=%s\n", pri->pname, mode, s);
else {
(void) printf("%s\t%s\tencoding=%u\n",
pri->pname, mode, au_pr->encoding);
}
/*
* The following values control audio device configuration
*/
(void) printf(
"%s\t%s\tgain=%u buffer_size=%u\n",
pri->pname, mode,
au_pr->gain,
au_pr->buffer_size);
show_audio_ports(pri, mode, "port", au_pr->port);
show_audio_ports(pri, mode, "avail_ports", au_pr->avail_ports);
show_audio_ports(pri, mode, "mod_ports", au_pr->mod_ports);
/*
* The following values describe driver state
*/
(void) printf("%s\t%s\tsamples=%u eof=%u pause=%u error=%u\n",
pri->pname, mode,
au_pr->samples,
au_pr->eof,
au_pr->pause,
au_pr->error);
(void) printf("%s\t%s\twaiting=%u balance=%u minordev=%u\n",
pri->pname, mode,
au_pr->waiting,
au_pr->balance,
au_pr->minordev);
/*
* The following values are read-only state flags
*/
(void) printf("%s\t%s\topen=%u active=%u\n",
pri->pname, mode,
au_pr->open,
au_pr->active);
}
void
show_audio_info(private_t *pri, long offset)
{
struct audio_info au;
if (Pread(Proc, &au, sizeof (au), offset) == sizeof (au)) {
show_audio_prinfo(pri, "play", &au.play);
show_audio_prinfo(pri, "record", &au.record);
(void) printf("%s\tmonitor_gain=%u output_muted=%u\n",
pri->pname, au.monitor_gain, au.output_muted);
show_audio_features(pri, audio_hw_features, au.hw_features,
"hw_features");
show_audio_features(pri, audio_sw_features, au.sw_features,
"sw_features");
show_audio_features(pri, audio_sw_features,
au.sw_features_enabled, "sw_features_enabled");
}
}
void
show_ioctl(private_t *pri, int code, long offset)
{
int lp64 = (data_model == PR_MODEL_LP64);
int err = pri->Errno; /* don't display output parameters */
/* for a failed system call */
#ifndef _LP64
if (lp64)
return;
#endif
if (offset == NULL)
return;
switch (code) {
case TCGETA:
if (err)
break;
/*FALLTHROUGH*/
case TCSETA:
case TCSETAW:
case TCSETAF:
show_termio(pri, offset);
break;
case TCGETS:
if (err)
break;
/*FALLTHROUGH*/
case TCSETS:
case TCSETSW:
case TCSETSF:
show_termios(pri, offset);
break;
case TCGETX:
if (err)
break;
/*FALLTHROUGH*/
case TCSETX:
case TCSETXW:
case TCSETXF:
show_termiox(pri, offset);
break;
case TIOCGETP:
if (err)
break;
/*FALLTHROUGH*/
case TIOCSETN:
case TIOCSETP:
show_sgttyb(pri, offset);
break;
case TIOCGLTC:
if (err)
break;
/*FALLTHROUGH*/
case TIOCSLTC:
show_ltchars(pri, offset);
break;
case TIOCGETC:
if (err)
break;
/*FALLTHROUGH*/
case TIOCSETC:
show_tchars(pri, offset);
break;
case LDGETT:
if (err)
break;
/*FALLTHROUGH*/
case LDSETT:
show_termcb(pri, offset);
break;
/* streams ioctl()s */
#if 0
/* these are displayed as strings in the arg list */
/* by prt_ioa(). don't display them again here */
case I_PUSH:
case I_LOOK:
case I_FIND:
/* these are displayed as decimal in the arg list */
/* by prt_ioa(). don't display them again here */
case I_LINK:
case I_UNLINK:
case I_SENDFD:
/* these are displayed symbolically in the arg list */
/* by prt_ioa(). don't display them again here */
case I_SRDOPT:
case I_SETSIG:
case I_FLUSH:
break;
/* this one just ignores the argument */
case I_POP:
break;
#endif
/* these return something in an int pointed to by arg */
case I_NREAD:
case I_GRDOPT:
case I_GETSIG:
case TIOCGSID:
case TIOCGPGRP:
case TIOCLGET:
case FIONREAD:
case FIORDCHK:
if (err)
break;
/*FALLTHROUGH*/
/* these pass something in an int pointed to by arg */
case TIOCSPGRP:
case TIOCFLUSH:
case TIOCLBIS:
case TIOCLBIC:
case TIOCLSET:
show_strint(pri, code, offset);
break;
/* these all point to structures */
case I_STR:
#ifdef _LP64
if (lp64)
show_strioctl(pri, offset);
else
show_strioctl32(pri, offset);
#else
show_strioctl(pri, offset);
#endif
break;
case I_PEEK:
#ifdef _LP64
if (lp64)
show_strpeek(pri, offset);
else
show_strpeek32(pri, offset);
#else
show_strpeek(pri, offset);
#endif
break;
case I_FDINSERT:
#ifdef _LP64
if (lp64)
show_strfdinsert(pri, offset);
else
show_strfdinsert32(pri, offset);
#else
show_strfdinsert(pri, offset);
#endif
break;
case I_RECVFD:
if (err)
break;
show_strrecvfd(pri, offset);
break;
case I_LIST:
if (err)
break;
#ifdef _LP64
if (lp64)
show_strlist(pri, offset);
else
show_strlist32(pri, offset);
#else
show_strlist(pri, offset);
#endif
break;
case JWINSIZE:
if (err)
break;
show_jwinsize(pri, offset);
break;
case TIOCGWINSZ:
if (err)
break;
/*FALLTHROUGH*/
case TIOCSWINSZ:
show_winsize(pri, offset);
break;
case AUDIO_GETINFO:
case (int)AUDIO_SETINFO:
show_audio_info(pri, offset);
break;
default:
if (code & IOC_INOUT) {
const char *str = ioctldatastruct(code);
(void) printf("\t\t%s",
(code & IOC_INOUT) == IOC_INOUT ? "write/read" :
code & IOC_IN ? "write" : "read");
if (str != NULL) {
(void) printf(" (struct %s)\n", str);
} else {
(void) printf(" %d bytes\n",
(code >> 16) & IOCPARM_MASK);
}
}
}
}
void
show_statvfs(private_t *pri)
{
long offset;
struct statvfs statvfs;
char *cp;
if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL &&
Pread(Proc, &statvfs, sizeof (statvfs), offset)
== sizeof (statvfs)) {
(void) printf(
"%s\tbsize=%-10lu frsize=%-9lu blocks=%-8llu bfree=%-9llu\n",
pri->pname,
statvfs.f_bsize,
statvfs.f_frsize,
(u_longlong_t)statvfs.f_blocks,
(u_longlong_t)statvfs.f_bfree);
(void) printf(
"%s\tbavail=%-9llu files=%-10llu ffree=%-9llu favail=%-9llu\n",
pri->pname,
(u_longlong_t)statvfs.f_bavail,
(u_longlong_t)statvfs.f_files,
(u_longlong_t)statvfs.f_ffree,
(u_longlong_t)statvfs.f_favail);
(void) printf(
"%s\tfsid=0x%-9.4lX basetype=%-7.16s namemax=%ld\n",
pri->pname,
statvfs.f_fsid,
statvfs.f_basetype,
(long)statvfs.f_namemax);
(void) printf(
"%s\tflag=%s\n",
pri->pname,
svfsflags(pri, (ulong_t)statvfs.f_flag));
cp = statvfs.f_fstr + strlen(statvfs.f_fstr);
if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 &&
*(cp+1) != '\0')
*cp = ' ';
(void) printf("%s\tfstr=\"%.*s\"\n",
pri->pname,
(int)sizeof (statvfs.f_fstr),
statvfs.f_fstr);
}
}
#ifdef _LP64
void
show_statvfs32(private_t *pri)
{
long offset;
struct statvfs32 statvfs;
char *cp;
if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL &&
Pread(Proc, &statvfs, sizeof (statvfs), offset)
== sizeof (statvfs)) {
(void) printf(
"%s\tbsize=%-10u frsize=%-9u blocks=%-8u bfree=%-9u\n",
pri->pname,
statvfs.f_bsize,
statvfs.f_frsize,
statvfs.f_blocks,
statvfs.f_bfree);
(void) printf(
"%s\tbavail=%-9u files=%-10u ffree=%-9u favail=%-9u\n",
pri->pname,
statvfs.f_bavail,
statvfs.f_files,
statvfs.f_ffree,
statvfs.f_favail);
(void) printf(
"%s\tfsid=0x%-9.4X basetype=%-7.16s namemax=%d\n",
pri->pname,
statvfs.f_fsid,
statvfs.f_basetype,
(int)statvfs.f_namemax);
(void) printf(
"%s\tflag=%s\n",
pri->pname,
svfsflags(pri, (ulong_t)statvfs.f_flag));
cp = statvfs.f_fstr + strlen(statvfs.f_fstr);
if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 &&
*(cp+1) != '\0')
*cp = ' ';
(void) printf("%s\tfstr=\"%.*s\"\n",
pri->pname,
(int)sizeof (statvfs.f_fstr),
statvfs.f_fstr);
}
}
#endif /* _LP64 */
void
show_statvfs64(private_t *pri)
{
long offset;
struct statvfs64_32 statvfs;
char *cp;
if (pri->sys_nargs > 1 && (offset = pri->sys_args[1]) != NULL &&
Pread(Proc, &statvfs, sizeof (statvfs), offset)
== sizeof (statvfs)) {
(void) printf(
"%s\tbsize=%-10u frsize=%-9u blocks=%-8llu bfree=%-9llu\n",
pri->pname,
statvfs.f_bsize,
statvfs.f_frsize,
(u_longlong_t)statvfs.f_blocks,
(u_longlong_t)statvfs.f_bfree);
(void) printf(
"%s\tbavail=%-9llu files=%-10llu ffree=%-9llu favail=%-9llu\n",
pri->pname,
(u_longlong_t)statvfs.f_bavail,
(u_longlong_t)statvfs.f_files,
(u_longlong_t)statvfs.f_ffree,
(u_longlong_t)statvfs.f_favail);
(void) printf(
"%s\tfsid=0x%-9.4X basetype=%-7.16s namemax=%d\n",
pri->pname,
statvfs.f_fsid,
statvfs.f_basetype,
(int)statvfs.f_namemax);
(void) printf(
"%s\tflag=%s\n",
pri->pname,
svfsflags(pri, (ulong_t)statvfs.f_flag));
cp = statvfs.f_fstr + strlen(statvfs.f_fstr);
if (cp < statvfs.f_fstr + sizeof (statvfs.f_fstr) - 1 &&
*(cp+1) != '\0')
*cp = ' ';
(void) printf("%s\tfstr=\"%.*s\"\n",
pri->pname,
(int)sizeof (statvfs.f_fstr),
statvfs.f_fstr);
}
}
void
show_statfs(private_t *pri)
{
long offset;
struct statfs statfs;
if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL &&
Pread(Proc, &statfs, sizeof (statfs), offset) == sizeof (statfs)) {
(void) printf(
"%s\tfty=%d bsz=%ld fsz=%ld blk=%ld bfr=%ld fil=%lu ffr=%lu\n",
pri->pname,
statfs.f_fstyp,
statfs.f_bsize,
statfs.f_frsize,
statfs.f_blocks,
statfs.f_bfree,
statfs.f_files,
statfs.f_ffree);
(void) printf("%s\t fname=%.6s fpack=%.6s\n",
pri->pname,
statfs.f_fname,
statfs.f_fpack);
}
}
#ifdef _LP64
void
show_statfs32(private_t *pri)
{
long offset;
struct statfs32 statfs;
if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL &&
Pread(Proc, &statfs, sizeof (statfs), offset) == sizeof (statfs)) {
(void) printf(
"%s\tfty=%d bsz=%d fsz=%d blk=%d bfr=%d fil=%u ffr=%u\n",
pri->pname,
statfs.f_fstyp,
statfs.f_bsize,
statfs.f_frsize,
statfs.f_blocks,
statfs.f_bfree,
statfs.f_files,
statfs.f_ffree);
(void) printf("%s\t fname=%.6s fpack=%.6s\n",
pri->pname,
statfs.f_fname,
statfs.f_fpack);
}
}
#endif /* _LP64 */
void
show_flock32(private_t *pri, long offset)
{
struct flock32 flock;
if (Pread(Proc, &flock, sizeof (flock), offset) == sizeof (flock)) {
const char *str = NULL;
(void) printf("%s\ttyp=", pri->pname);
switch (flock.l_type) {
case F_RDLCK:
str = "F_RDLCK";
break;
case F_WRLCK:
str = "F_WRLCK";
break;
case F_UNLCK:
str = "F_UNLCK";
break;
}
if (str != NULL)
(void) printf("%s", str);
else
(void) printf("%-7d", flock.l_type);
str = whencearg(flock.l_whence);
if (str != NULL)
(void) printf(" whence=%s", str);
else
(void) printf(" whence=%-8u", flock.l_whence);
(void) printf(
" start=%-5d len=%-5d sys=%-2u pid=%d\n",
flock.l_start,
flock.l_len,
flock.l_sysid,
flock.l_pid);
}
}
void
show_flock64(private_t *pri, long offset)
{
struct flock64 flock;
if (Pread(Proc, &flock, sizeof (flock), offset) == sizeof (flock)) {
const char *str = NULL;
(void) printf("%s\ttyp=", pri->pname);
switch (flock.l_type) {
case F_RDLCK:
str = "F_RDLCK";
break;
case F_WRLCK:
str = "F_WRLCK";
break;
case F_UNLCK:
str = "F_UNLCK";
break;
}
if (str != NULL)
(void) printf("%s", str);
else
(void) printf("%-7d", flock.l_type);
str = whencearg(flock.l_whence);
if (str != NULL)
(void) printf(" whence=%s", str);
else
(void) printf(" whence=%-8u", flock.l_whence);
(void) printf(
" start=%-5lld len=%-5lld sys=%-2u pid=%d\n",
(long long)flock.l_start,
(long long)flock.l_len,
flock.l_sysid,
(int)flock.l_pid);
}
}
void
show_share(private_t *pri, long offset)
{
struct fshare fshare;
if (Pread(Proc, &fshare, sizeof (fshare), offset) == sizeof (fshare)) {
const char *str = NULL;
int manddny = 0;
(void) printf("%s\taccess=", pri->pname);
switch (fshare.f_access) {
case F_RDACC:
str = "F_RDACC";
break;
case F_WRACC:
str = "F_WRACC";
break;
case F_RWACC:
str = "F_RWACC";
break;
}
if (str != NULL)
(void) printf("%s", str);
else
(void) printf("%-7d", fshare.f_access);
str = NULL;
if (fshare.f_deny & F_MANDDNY) {
fshare.f_deny &= ~F_MANDDNY;
manddny = 1;
}
switch (fshare.f_deny) {
case F_NODNY:
str = "F_NODNY";
break;
case F_RDDNY:
str = "F_RDDNY";
break;
case F_WRDNY:
str = "F_WRDNY";
break;
case F_RWDNY:
str = "F_RWDNY";
break;
case F_COMPAT:
str = "F_COMPAT";
break;
}
if (str != NULL) {
if (manddny)
(void) printf(" deny=F_MANDDNY|%s", str);
else
(void) printf(" deny=%s", str);
} else {
(void) printf(" deny=0x%x", manddny?
fshare.f_deny | F_MANDDNY : fshare.f_deny);
}
(void) printf(" id=%x\n", fshare.f_id);
}
}
void
show_ffg(private_t *pri)
{
(void) putchar('\t');
(void) putchar('\t');
prt_ffg(pri, 0, pri->Rval1);
(void) puts(pri->sys_string);
}
/* print values in fcntl() pointed-to structure */
void
show_fcntl(private_t *pri)
{
long offset;
if (pri->sys_nargs >= 2 && pri->sys_args[1] == F_GETFL) {
show_ffg(pri);
return;
}
if (pri->sys_nargs < 3 || (offset = pri->sys_args[2]) == NULL)
return;
switch (pri->sys_args[1]) {
#ifdef _LP64
case F_GETLK:
case F_SETLK:
case F_SETLKW:
case F_FREESP:
case F_ALLOCSP:
case F_SETLK_NBMAND:
if (data_model == PR_MODEL_LP64)
show_flock64(pri, offset);
else
show_flock32(pri, offset);
break;
case 33: /* F_GETLK64 */
case 34: /* F_SETLK64 */
case 35: /* F_SETLKW64 */
case 27: /* F_FREESP64 */
case 44: /* F_SETLK64_NBMAND */
show_flock64(pri, offset);
break;
#else /* _LP64 */
case F_GETLK:
case F_SETLK:
case F_SETLKW:
case F_FREESP:
case F_ALLOCSP:
case F_SETLK_NBMAND:
show_flock32(pri, offset);
break;
case F_GETLK64:
case F_SETLK64:
case F_SETLKW64:
case F_FREESP64:
case F_SETLK64_NBMAND:
show_flock64(pri, offset);
break;
#endif /* _LP64 */
case F_SHARE:
case F_UNSHARE:
show_share(pri, offset);
break;
}
}
void
show_strbuf(private_t *pri, long offset, const char *name, int dump)
{
struct strbuf strbuf;
if (Pread(Proc, &strbuf, sizeof (strbuf), offset) == sizeof (strbuf))
print_strbuf(pri, &strbuf, name, dump);
}
#ifdef _LP64
void
show_strbuf32(private_t *pri, long offset, const char *name, int dump)
{
struct strbuf32 strbuf;
if (Pread(Proc, &strbuf, sizeof (strbuf), offset) == sizeof (strbuf))
print_strbuf32(pri, &strbuf, name, dump);
}
#endif /* _LP64 */
void
show_gp_msg(private_t *pri, int what)
{
long offset;
int dump = FALSE;
int fdp1 = pri->sys_args[0] + 1;
switch (what) {
case SYS_getmsg:
case SYS_getpmsg:
if (pri->Errno == 0 && prismember(&readfd, fdp1))
dump = TRUE;
break;
case SYS_putmsg:
case SYS_putpmsg:
if (prismember(&writefd, fdp1))
dump = TRUE;
break;
}
/* enter region of lengthy output */
if (dump)
Eserialize();
#ifdef _LP64
if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL) {
if (data_model == PR_MODEL_LP64)
show_strbuf(pri, offset, "ctl", dump);
else
show_strbuf32(pri, offset, "ctl", dump);
}
if (pri->sys_nargs >= 3 && (offset = pri->sys_args[2]) != NULL) {
if (data_model == PR_MODEL_LP64)
show_strbuf(pri, offset, "dat", dump);
else
show_strbuf32(pri, offset, "dat", dump);
}
#else /* _LP64 */
if (pri->sys_nargs >= 2 && (offset = pri->sys_args[1]) != NULL)
show_strbuf(pri, offset, "ctl", dump);
if (pri->sys_nargs >= 3 && (offset = pri->sys_args[2]) != NULL)
show_strbuf(pri, offset, "dat", dump);
#endif /* _LP64 */
/* exit region of lengthy output */
if (dump)
Xserialize();
}
void
show_int(private_t *pri, long offset, const char *name)
{
int value;
if (offset != 0 &&
Pread(Proc, &value, sizeof (value), offset) == sizeof (value))
(void) printf("%s\t%s:\t%d\n",
pri->pname,
name,
value);
}
void
show_hhex_int(private_t *pri, long offset, const char *name)
{
int value;
if (Pread(Proc, &value, sizeof (value), offset) == sizeof (value))
(void) printf("%s\t%s:\t0x%.4X\n",
pri->pname,
name,
value);
}
#define ALL_POLL_FLAGS (POLLIN|POLLPRI|POLLOUT| \
POLLRDNORM|POLLRDBAND|POLLWRBAND|POLLERR|POLLHUP|POLLNVAL)
const char *
pollevent(private_t *pri, int arg)
{
char *str = pri->code_buf;
if (arg == 0)
return ("0");
if (arg & ~ALL_POLL_FLAGS) {
(void) sprintf(str, "0x%-5X", arg);
return ((const char *)str);
}
*str = '\0';
if (arg & POLLIN)
(void) strcat(str, "|POLLIN");
if (arg & POLLPRI)
(void) strcat(str, "|POLLPRI");
if (arg & POLLOUT)
(void) strcat(str, "|POLLOUT");
if (arg & POLLRDNORM)
(void) strcat(str, "|POLLRDNORM");
if (arg & POLLRDBAND)
(void) strcat(str, "|POLLRDBAND");
if (arg & POLLWRBAND)
(void) strcat(str, "|POLLWRBAND");
if (arg & POLLERR)
(void) strcat(str, "|POLLERR");
if (arg & POLLHUP)
(void) strcat(str, "|POLLHUP");
if (arg & POLLNVAL)
(void) strcat(str, "|POLLNVAL");
return ((const char *)(str+1));
}
static void
show_one_pollfd(private_t *pri, struct pollfd *ppollfd)
{
/*
* can't print both events and revents in same printf.
* pollevent() returns a pointer to a TSD location.
*/
(void) printf("%s\tfd=%-2d ev=%s",
pri->pname, ppollfd->fd, pollevent(pri, ppollfd->events));
(void) printf(" rev=%s\n", pollevent(pri, ppollfd->revents));
}
static void
show_all_pollfds(private_t *pri, long offset, int nfds)
{
struct pollfd pollfd[2];
int skip = -1;
for (; nfds && !interrupt; nfds--, offset += sizeof (struct pollfd)) {
if (Pread(Proc, &pollfd[0], sizeof (struct pollfd), offset) !=
sizeof (struct pollfd))
continue;
if (skip >= 0 && pollfd[0].fd == pollfd[1].fd &&
pollfd[0].events == pollfd[1].events &&
pollfd[0].revents == pollfd[1].revents) {
skip++;
continue;
}
if (skip > 0)
(void) printf("%s\t...last pollfd structure"
" repeated %d time%s...\n",
pri->pname, skip, (skip == 1 ? "" : "s"));
skip = 0;
show_one_pollfd(pri, &pollfd[0]);
pollfd[1] = pollfd[0];
}
if (skip > 0)
(void) printf(
"%s\t...last pollfd structure repeated %d time%s...\n",
pri->pname, skip, (skip == 1 ? "" : "s"));
}
void
show_poll(private_t *pri)
{
long offset;
int nfds;
int serial = 0;
if (pri->sys_nargs < 2 || (offset = pri->sys_args[0]) == NULL ||
(nfds = pri->sys_args[1]) <= 0)
return;
/* enter region of lengthy output */
if (nfds > 32) {
Eserialize();
serial = 1;
}
show_all_pollfds(pri, offset, nfds);
/* exit region of lengthy output */
if (serial)
Xserialize();
}
void
show_pollsys(private_t *pri)
{
long offset;
int nfds;
int serial = 0;
if (pri->sys_nargs < 2)
return;
offset = pri->sys_args[0];
nfds = pri->sys_args[1];
/* enter region of lengthy output */
if (offset != NULL && nfds > 32) {
Eserialize();
serial = 1;
}
if (offset != NULL && nfds > 0)
show_all_pollfds(pri, offset, nfds);
if (pri->sys_nargs > 2)
show_timestruc(pri, (long)pri->sys_args[2], "timeout");
if (pri->sys_nargs > 3)
show_sigset(pri, (long)pri->sys_args[3], "sigmask");
/* exit region of lengthy output */
if (serial)
Xserialize();
}
static void
show_perm64(private_t *pri, struct ipc_perm64 *ip)
{
(void) printf("%s\tu=%-5d g=%-5d cu=%-5d cg=%-5d z=%-5d "
"m=0%.6o key=%d projid=%-5d\n",
pri->pname,
(int)ip->ipcx_uid,
(int)ip->ipcx_gid,
(int)ip->ipcx_cuid,
(int)ip->ipcx_cgid,
(int)ip->ipcx_zoneid,
(unsigned int)ip->ipcx_mode,
ip->ipcx_key,
(int)ip->ipcx_projid);
}
void
show_perm(private_t *pri, struct ipc_perm *ip)
{
(void) printf(
"%s\tu=%-5u g=%-5u cu=%-5u cg=%-5u m=0%.6o seq=%u key=%d\n",
pri->pname,
(int)ip->uid,
(int)ip->gid,
(int)ip->cuid,
(int)ip->cgid,
(int)ip->mode,
ip->seq,
ip->key);
}
#ifdef _LP64
void
show_perm32(private_t *pri, struct ipc_perm32 *ip)
{
(void) printf(
"%s\tu=%-5u g=%-5u cu=%-5u cg=%-5u m=0%.6o seq=%u key=%d\n",
pri->pname,
ip->uid,
ip->gid,
ip->cuid,
ip->cgid,
ip->mode,
ip->seq,
ip->key);
}
#endif /* _LP64 */
static void
show_msgctl64(private_t *pri, long offset)
{
struct msqid_ds64 msgq;
if (offset != NULL &&
Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) {
show_perm64(pri, &msgq.msgx_perm);
(void) printf("%s\tbytes=%-5llu msgs=%-5llu maxby=%-5llu "
"lspid=%-5d lrpid=%-5d\n", pri->pname,
(unsigned long long)msgq.msgx_cbytes,
(unsigned long long)msgq.msgx_qnum,
(unsigned long long)msgq.msgx_qbytes,
(int)msgq.msgx_lspid,
(int)msgq.msgx_lrpid);
prtime(pri, " st = ", (time_t)msgq.msgx_stime);
prtime(pri, " rt = ", (time_t)msgq.msgx_rtime);
prtime(pri, " ct = ", (time_t)msgq.msgx_ctime);
}
}
void
show_msgctl(private_t *pri, long offset)
{
struct msqid_ds msgq;
if (offset != NULL &&
Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) {
show_perm(pri, &msgq.msg_perm);
(void) printf(
"%s\tbytes=%-5lu msgs=%-5lu maxby=%-5lu lspid=%-5u lrpid=%-5u\n",
pri->pname,
msgq.msg_cbytes,
msgq.msg_qnum,
msgq.msg_qbytes,
(int)msgq.msg_lspid,
(int)msgq.msg_lrpid);
prtime(pri, " st = ", msgq.msg_stime);
prtime(pri, " rt = ", msgq.msg_rtime);
prtime(pri, " ct = ", msgq.msg_ctime);
}
}
#ifdef _LP64
void
show_msgctl32(private_t *pri, long offset)
{
struct msqid_ds32 msgq;
if (offset != NULL &&
Pread(Proc, &msgq, sizeof (msgq), offset) == sizeof (msgq)) {
show_perm32(pri, &msgq.msg_perm);
(void) printf(
"%s\tbytes=%-5u msgs=%-5u maxby=%-5u lspid=%-5u lrpid=%-5u\n",
pri->pname,
msgq.msg_cbytes,
msgq.msg_qnum,
msgq.msg_qbytes,
msgq.msg_lspid,
msgq.msg_lrpid);
prtime(pri, " st = ", msgq.msg_stime);
prtime(pri, " rt = ", msgq.msg_rtime);
prtime(pri, " ct = ", msgq.msg_ctime);
}
}
#endif /* _LP64 */
void
show_msgbuf(private_t *pri, long offset, long msgsz)
{
struct msgbuf msgb;
if (offset != NULL &&
Pread(Proc, &msgb, sizeof (msgb.mtype), offset) ==
sizeof (msgb.mtype)) {
/* enter region of lengthy output */
if (msgsz > MYBUFSIZ / 4)
Eserialize();
(void) printf("%s\tmtype=%lu mtext[]=\n",
pri->pname,
msgb.mtype);
showbuffer(pri,
(long)(offset + sizeof (msgb.mtype)), msgsz);
/* exit region of lengthy output */
if (msgsz > MYBUFSIZ / 4)
Xserialize();
}
}
#ifdef _LP64
void
show_msgbuf32(private_t *pri, long offset, long msgsz)
{
struct ipcmsgbuf32 msgb;
if (offset != NULL &&
Pread(Proc, &msgb, sizeof (msgb.mtype), offset) ==
sizeof (msgb.mtype)) {
/* enter region of lengthy output */
if (msgsz > MYBUFSIZ / 4)
Eserialize();
(void) printf("%s\tmtype=%u mtext[]=\n",
pri->pname,
msgb.mtype);
showbuffer(pri,
(long)(offset + sizeof (msgb.mtype)), msgsz);
/* exit region of lengthy output */
if (msgsz > MYBUFSIZ / 4)
Xserialize();
}
}
#endif /* _LP64 */
#ifdef _LP64
void
show_msgsys(private_t *pri, long msgsz)
{
switch (pri->sys_args[0]) {
case 0: /* msgget() */
break;
case 1: /* msgctl() */
if (pri->sys_nargs > 3) {
switch (pri->sys_args[2]) {
case IPC_STAT:
if (pri->Errno)
break;
/*FALLTHROUGH*/
case IPC_SET:
if (data_model == PR_MODEL_LP64)
show_msgctl(pri,
(long)pri->sys_args[3]);
else
show_msgctl32(pri,
(long)pri->sys_args[3]);
break;
case IPC_STAT64:
if (pri->Errno)
break;
/*FALLTHROUGH*/
case IPC_SET64:
show_msgctl64(pri, (long)pri->sys_args[3]);
break;
}
}
break;
case 2: /* msgrcv() */
if (!pri->Errno && pri->sys_nargs > 2) {
if (data_model == PR_MODEL_LP64)
show_msgbuf(pri, pri->sys_args[2], msgsz);
else
show_msgbuf32(pri, pri->sys_args[2], msgsz);
}
break;
case 3: /* msgsnd() */
if (pri->sys_nargs > 3) {
if (data_model == PR_MODEL_LP64)
show_msgbuf(pri, pri->sys_args[2],
pri->sys_args[3]);
else
show_msgbuf32(pri, pri->sys_args[2],
pri->sys_args[3]);
}
break;
case 4: /* msgids() */
case 5: /* msgsnap() */
default: /* unexpected subcode */
break;
}
}
#else /* _LP64 */
void
show_msgsys(private_t *pri, long msgsz)
{
switch (pri->sys_args[0]) {
case 0: /* msgget() */
break;
case 1: /* msgctl() */
if (pri->sys_nargs > 3) {
switch (pri->sys_args[2]) {
case IPC_STAT:
if (pri->Errno)
break;
/*FALLTHROUGH*/
case IPC_SET:
show_msgctl(pri, (long)pri->sys_args[3]);
break;
case IPC_STAT64:
if (pri->Errno)
break;
/*FALLTHROUGH*/
case IPC_SET64:
show_msgctl64(pri, (long)pri->sys_args[3]);
break;
}
}
break;
case 2: /* msgrcv() */
if (!pri->Errno && pri->sys_nargs > 2)
show_msgbuf(pri, pri->sys_args[2], msgsz);
break;
case 3: /* msgsnd() */
if (pri->sys_nargs > 3)
show_msgbuf(pri, pri->sys_args[2],
pri->sys_args[3]);
break;
case 4: /* msgids() */
case 5: /* msgsnap() */
default: /* unexpected subcode */
break;
}
}
#endif /* _LP64 */
static void
show_semctl64(private_t *pri, long offset)
{
struct semid_ds64 semds;
if (offset != NULL &&
Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) {
show_perm64(pri, &semds.semx_perm);
(void) printf("%s\tnsems=%u\n", pri->pname, semds.semx_nsems);
prtime(pri, " ot = ", (time_t)semds.semx_otime);
prtime(pri, " ct = ", (time_t)semds.semx_ctime);
}
}
void
show_semctl(private_t *pri, long offset)
{
struct semid_ds semds;
if (offset != NULL &&
Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) {
show_perm(pri, &semds.sem_perm);
(void) printf("%s\tnsems=%u\n",
pri->pname,
semds.sem_nsems);
prtime(pri, " ot = ", semds.sem_otime);
prtime(pri, " ct = ", semds.sem_ctime);
}
}
#ifdef _LP64
void
show_semctl32(private_t *pri, long offset)
{
struct semid_ds32 semds;
if (offset != NULL &&
Pread(Proc, &semds, sizeof (semds), offset) == sizeof (semds)) {
show_perm32(pri, &semds.sem_perm);
(void) printf("%s\tnsems=%u\n",
pri->pname,
semds.sem_nsems);
prtime(pri, " ot = ", semds.sem_otime);
prtime(pri, " ct = ", semds.sem_ctime);
}
}
#endif /* _LP64 */
void
show_semop(private_t *pri, long offset, long nsops, long timeout)
{
struct sembuf sembuf;
const char *str;
if (offset == NULL)
return;
if (nsops > 40) /* let's not be ridiculous */
nsops = 40;
for (; nsops > 0 && !interrupt; --nsops, offset += sizeof (sembuf)) {
if (Pread(Proc, &sembuf, sizeof (sembuf), offset) !=
sizeof (sembuf))
break;
(void) printf("%s\tsemnum=%-5u semop=%-5d semflg=",
pri->pname,
sembuf.sem_num,
sembuf.sem_op);
if (sembuf.sem_flg == 0)
(void) printf("0\n");
else if ((str = semflags(pri, sembuf.sem_flg)) != NULL)
(void) printf("%s\n", str);
else
(void) printf("0%.6o\n", sembuf.sem_flg);
}
if (timeout)
show_timestruc(pri, timeout, "timeout");
}
void
show_semsys(private_t *pri)
{
switch (pri->sys_args[0]) {
case 0: /* semctl() */
if (pri->sys_nargs > 4) {
switch (pri->sys_args[3]) {
case IPC_STAT:
if (pri->Errno)
break;
/*FALLTHROUGH*/
case IPC_SET:
#ifdef _LP64
if (data_model == PR_MODEL_LP64)
show_semctl(pri,
(long)pri->sys_args[4]);
else
show_semctl32(pri,
(long)pri->sys_args[4]);
#else
show_semctl(pri, (long)pri->sys_args[4]);
#endif
break;
case IPC_STAT64:
if (pri->Errno)
break;
/*FALLTHROUGH*/
case IPC_SET64:
show_semctl64(pri, (long)pri->sys_args[4]);
break;
}
}
break;
case 1: /* semget() */
break;
case 2: /* semop() */
if (pri->sys_nargs > 3)
show_semop(pri, (long)pri->sys_args[2],
pri->sys_args[3], 0);
break;
case 3: /* semids() */
break;
case 4: /* semtimedop() */
if (pri->sys_nargs > 4)
show_semop(pri, (long)pri->sys_args[2],
pri->sys_args[3], pri->sys_args[4]);
break;
default: /* unexpected subcode */
break;
}
}
static void
show_shmctl64(private_t *pri, long offset)
{
struct shmid_ds64 shmds;
if (offset != NULL &&
Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) {
show_perm64(pri, &shmds.shmx_perm);
(void) printf(
"%s\tsize=%-6llu lpid=%-5d cpid=%-5d na=%-5llu cna=%llu\n",
pri->pname,
(unsigned long long)shmds.shmx_segsz,
(int)shmds.shmx_lpid,
(int)shmds.shmx_cpid,
(unsigned long long)shmds.shmx_nattch,
(unsigned long long)shmds.shmx_cnattch);
prtime(pri, " at = ", (time_t)shmds.shmx_atime);
prtime(pri, " dt = ", (time_t)shmds.shmx_dtime);
prtime(pri, " ct = ", (time_t)shmds.shmx_ctime);
}
}
void
show_shmctl(private_t *pri, long offset)
{
struct shmid_ds shmds;
if (offset != NULL &&
Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) {
show_perm(pri, &shmds.shm_perm);
(void) printf(
"%s\tsize=%-6lu lpid=%-5u cpid=%-5u na=%-5lu cna=%lu\n",
pri->pname,
(ulong_t)shmds.shm_segsz,
(int)shmds.shm_lpid,
(int)shmds.shm_cpid,
shmds.shm_nattch,
shmds.shm_cnattch);
prtime(pri, " at = ", shmds.shm_atime);
prtime(pri, " dt = ", shmds.shm_dtime);
prtime(pri, " ct = ", shmds.shm_ctime);
}
}
#ifdef _LP64
void
show_shmctl32(private_t *pri, long offset)
{
struct shmid_ds32 shmds;
if (offset != NULL &&
Pread(Proc, &shmds, sizeof (shmds), offset) == sizeof (shmds)) {
show_perm32(pri, &shmds.shm_perm);
(void) printf(
"%s\tsize=%-6u lpid=%-5u cpid=%-5u na=%-5u cna=%u\n",
pri->pname,
shmds.shm_segsz,
shmds.shm_lpid,
shmds.shm_cpid,
shmds.shm_nattch,
shmds.shm_cnattch);
prtime(pri, " at = ", shmds.shm_atime);
prtime(pri, " dt = ", shmds.shm_dtime);
prtime(pri, " ct = ", shmds.shm_ctime);
}
}
#endif /* _LP64 */
void
show_shmsys(private_t *pri)
{
switch (pri->sys_args[0]) {
case 0: /* shmat() */
break;
case 1: /* shmctl() */
if (pri->sys_nargs > 3) {
switch (pri->sys_args[2]) {
case IPC_STAT:
if (pri->Errno)
break;
/*FALLTHROUGH*/
case IPC_SET:
#ifdef _LP64
if (data_model == PR_MODEL_LP64)
show_shmctl(pri,
(long)pri->sys_args[3]);
else
show_shmctl32(pri,
(long)pri->sys_args[3]);
#else
show_shmctl(pri, (long)pri->sys_args[3]);
#endif
break;
case IPC_STAT64:
if (pri->Errno)
break;
/*FALLTHROUGH*/
case IPC_SET64:
show_shmctl64(pri, (long)pri->sys_args[3]);
break;
}
}
break;
case 2: /* shmdt() */
case 3: /* shmget() */
case 4: /* shmids() */
default: /* unexpected subcode */
break;
}
}
void
show_groups(private_t *pri, long offset, long count)
{
int groups[100];
if (count > 100)
count = 100;
if (count > 0 && offset != NULL &&
Pread(Proc, &groups[0], count*sizeof (int), offset) ==
count*sizeof (int)) {
int n;
(void) printf("%s\t", pri->pname);
for (n = 0; !interrupt && n < count; n++) {
if (n != 0 && n%10 == 0)
(void) printf("\n%s\t", pri->pname);
(void) printf(" %5d", groups[n]);
}
(void) fputc('\n', stdout);
}
}
/*
* This assumes that a sigset_t is simply an array of ints.
*/
char *
sigset_string(private_t *pri, sigset_t *sp)
{
char *s = pri->code_buf;
int n = sizeof (*sp) / sizeof (int32_t);