/*
* 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
* 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
*/
/*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <libuutil.h>
#include <limits.h>
#include <libcontract.h>
#include <libcontract_priv.h>
#include <dirent.h>
#include <locale.h>
#include <langinfo.h>
#include "statcommon.h"
static int opt_verbose = 0;
static int opt_showall = 0;
/*
* usage
*
* Educate the user.
*/
static void
usage(void)
{
"[-t typelist] [-T d|u] [-v] [interval [count]]\n"), uu_getpname());
}
/*
* mystrtoul
*
* Convert a string into an int in [0, INT_MAX]. Exit if the argument
* doen't fit this description.
*/
static int
{
unsigned int result;
usage();
}
return (result);
}
/*
* int_compar
*
* A simple integer comparator. Also used for id_ts, since they're the
* same thing.
*/
static int
{
return (1);
return (-1);
return (0);
}
typedef struct optvect {
const char *option;
} optvect_t;
{ "inherit", CT_PR_INHERIT },
{ "noorphan", CT_PR_NOORPHAN },
{ "pgrponly", CT_PR_PGRPONLY },
{ "regent", CT_PR_REGENT },
{ NULL }
};
{ "core", CT_PR_EV_CORE },
{ "signal", CT_PR_EV_SIGNAL },
{ "hwerr", CT_PR_EV_HWERR },
{ "empty", CT_PR_EV_EMPTY },
{ "fork", CT_PR_EV_FORK },
{ "exit", CT_PR_EV_EXIT },
{ NULL }
};
/*
* print_bits
*
* Display a set whose membership is identified by a bitfield.
*/
static void
{
int i, printed = 0;
if (printed)
(void) putchar(' ');
printed = 1;
}
if (printed)
(void) putchar('\n');
else
(void) puts("none");
}
/*
* print_ids
*
* Display a list of ids, sorted.
*/
static void
{
int i;
for (i = 0; i < nids; i++) {
/*LINTED*/
first = 0;
}
if (first)
(void) puts("none");
else
(void) putchar('\n');
}
/*
* A structure defining a displayed field. Includes a label to be
* printed along side the field value, and a function which extracts
* the data from a status structure, formats it, and displays it on
* stdout.
*/
typedef struct verbout {
} verbout_t;
/*
* verb_cookie
*
* Used to display an error encountered when reading a contract status
* field.
*/
static void
{
}
/*
* verb_cookie
*
* Display the contract's cookie.
*/
static void
{
}
/*
* verb_info
*
* Display the parameters in the parameter set.
*/
static void
{
int err;
else
}
/*
* verb_info
*
* Display the events in the informative event set.
*/
static void
{
}
/*
* verb_crit
*
* Display the events in the critical event set.
*/
static void
{
}
/*
* verb_minor
*
* Display the minor device
*/
static void
{
int err;
char *buf;
else
}
/*
* verb_state
*
* Display the state of the device
*/
static void
{
int err;
else
}
/*
* verb_fatal
*
* Display the events in the fatal event set.
*/
static void
{
int err;
else
}
/*
* verb_members
*
* Display the list of member contracts.
*/
static void
{
int err;
return;
}
}
/*
* verb_inherit
*
* Display the list of inherited contracts.
*/
static void
{
int err;
else
}
/*
* verb_svc_fmri
*
* Display the process contract service fmri
*/
static void
{
char *svc_fmri;
int err;
else
}
/*
* verb_svc_aux
*
* Display the process contract service fmri auxiliar
*/
static void
{
char *svc_aux;
int err;
else
}
/*
* verb_svc_ctid
*
* Display the process contract service fmri ctid
*/
static void
{
int err;
else
}
/*
* verb_svc_creator
*
* Display the process contract creator's execname
*/
static void
{
char *svc_creator;
int err;
else
}
/*
* Common contract status fields.
*/
"cookie", verb_cookie,
NULL,
};
/*
* Process contract-specific status fields.
* The critical and informative event sets are here because the event
* names are contract-specific. They are listed first, however, so
* they are displayed adjacent to the "normal" common output.
*/
"informative event set", verb_info,
"critical event set", verb_crit,
"fatal event set", verb_fatal,
"parameter set", verb_param,
"member processes", verb_members,
"inherited contracts", verb_inherit,
"service fmri", verb_svc_fmri,
"service fmri ctid", verb_svc_ctid,
"creator", verb_svc_creator,
"aux", verb_svc_aux,
};
"device", verb_minor,
"dev_state", verb_dev_state,
};
/*
* print_verbose
*
* Displays a contract's verbose status, common fields first.
*/
static void
{
int i;
/*
* Compute the width of all the fields.
*/
if (spec)
maxwidth += 2;
/*
* Display the data.
*/
if (tmp < 0)
tmp = 0;
}
if (spec)
}
}
struct {
const char *name;
} cttypes[] = {
{ "process", vprocess },
{ "device", vdevice },
{ NULL }
};
/*
* get_type
*
* Given a type name, return an index into the above array of types.
*/
static int
{
int i;
return (i);
/* NOTREACHED */
}
/*
* print_header
*
* Display the status header.
*/
static void
print_header(void)
{
"TYPE", "STATE", "HOLDER", "EVENTS", "QTIME", "NTIME");
}
/*
* print_contract
*
* Display status for contract ID 'id' from type directory 'dir'. If
* only contracts of a specific set of types should be displayed,
* 'types' will be a sorted list of type indices of length 'ntypes'.
*/
static void
{
int fd = 0;
int t;
/*
* Open and obtain status.
*/
return;
}
&status))
/*
* Unless otherwise directed, don't display dead contracts.
*/
return;
}
/*
* If we are only allowed to display certain contract types,
* perform that filtering here. We stash a copy of spec so we
* don't have to recompute it later.
*/
if (types) {
NULL) {
return;
}
}
/*
* Precompute those fields which have both textual and
* numerical values.
*/
else
} else {
}
/*
* Emit the contract's status.
*/
(void) printf("%-7ld %-7ld %-7s %-7s %-7s %-7d %-7s %-8s\n",
/*
* Emit verbose status information, if requested. If we
* weren't provided a verbose output spec or didn't compute it
* earlier, do it now.
*/
if (opt_verbose) {
}
}
/*
* scan_type
*
* Display all contracts of the requested type.
*/
static void
{
/*
* Eliminate special files (e.g. '.', '..').
*/
continue;
}
}
/*
* scan_ids
*
* Display all contracts with the requested IDs.
*/
static void
{
int i;
for (i = 0; i < nids; i++)
}
/*
* scan_all
*
* Display the union of the requested IDs and types. So that the
* output is sorted by contract ID, it takes the slow road by testing
* the number of types is greater than 1, when we have a mixture of
* types and ids, or no lists were provided at all.
*/
static void
{
/*
* Eliminate special files (e.g. '.', '..').
*/
continue;
/*
* If we are given IDs to look at and this contract
* isn't in the ID list, or if we weren't given a list
* if IDs but were given a list of types, provide the
* list of acceptable types to print_contract.
*/
}
}
/*
* walk_args
*
* Apply fp to each token in the comma- or space- separated argument
* string str and store the results in the array starting at results.
*/
static int
{
int count = 0;
return (0);
}
do {
if (fp)
count++;
return (count);
}
/*
* parse
*
* Parse the comma- or space- separated string str, using fp to covert
* the tokens to integers. Append the list of integers to the array
* pointed to by *idps, growing the array if necessary.
*/
static int
{
int count;
int *array;
if (count == 0)
return (0);
if (*idsp) {
}
}
/*
* parse_ids
*
* Extract a list of ids from the comma- or space- separated string str
* and append them to the array *idsp, growing it if necessary.
*/
static int
{
}
/*
* parse_types
*
* Extract a list of types from the comma- or space- separated string
* str and append them to the array *idsp, growing it if necessary.
*/
static int
{
}
/*
* compact
*
* Sorts and removes duplicates from array. Initial size of array is
* in *size; final size is stored in *size.
*/
static void
{
for (i = j = 0; i < *size; i++) {
}
}
*size = j;
}
int
{
int i, s;
(void) textdomain(TEXT_DOMAIN);
(void) uu_setpname(argv[0]);
switch (s) {
case 'a':
opt_showall = 1;
break;
case 'i':
break;
case 'T':
if (optarg) {
if (*optarg == 'u')
else if (*optarg == 'd')
else
usage();
} else {
usage();
}
break;
case 't':
break;
case 'v':
opt_verbose = 1;
break;
default:
usage();
}
}
usage();
if (argc > 0) {
count = 0;
}
if (argc > 1) {
if (count == 0)
return (0);
}
if (nids)
if (ntypes)
if (i)
if (timestamp_fmt != NODATE)
print_header();
else if (ntypes == 1)
else if (nids)
else
}
return (0);
}