MFC
This commit is contained in:
parent
ddd6ad1bba
commit
e8310498d5
@ -32,7 +32,7 @@
|
||||
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 4, 2008
|
||||
.Dd September 28, 2011
|
||||
.Dt LS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -357,8 +357,7 @@ option is given,
|
||||
the numeric ID's are displayed.
|
||||
.Pp
|
||||
If the file is a character special or block special file,
|
||||
the major and minor device numbers for the file are displayed
|
||||
in the size field.
|
||||
the device number for the file is displayed in the size field.
|
||||
If the file is a symbolic link the pathname of the
|
||||
linked-to file is preceded by
|
||||
.Dq Li -> .
|
||||
|
41
bin/ls/ls.c
41
bin/ls/ls.c
@ -563,7 +563,7 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
long maxblock;
|
||||
u_long btotal, labelstrlen, maxinode, maxlen, maxnlink;
|
||||
u_long maxlabelstr;
|
||||
u_int devstrlen;
|
||||
u_int sizelen;
|
||||
int maxflags;
|
||||
gid_t maxgroup;
|
||||
uid_t maxuser;
|
||||
@ -572,7 +572,6 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
int entries, needstats;
|
||||
const char *user, *group;
|
||||
char *flags, *labelstr = NULL;
|
||||
char buf[STRBUF_SIZEOF(u_quad_t) + 1];
|
||||
char ngroup[STRBUF_SIZEOF(uid_t) + 1];
|
||||
char nuser[STRBUF_SIZEOF(gid_t) + 1];
|
||||
|
||||
@ -656,7 +655,8 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
MAKENINES(maxsize);
|
||||
free(jinitmax);
|
||||
}
|
||||
devstrlen = 0;
|
||||
d.s_size = 0;
|
||||
sizelen = 0;
|
||||
flags = NULL;
|
||||
for (cur = list, entries = 0; cur; cur = cur->fts_link) {
|
||||
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
|
||||
@ -796,14 +796,12 @@ label_out:
|
||||
np->group = &np->data[ulen + 1];
|
||||
(void)strcpy(np->group, group);
|
||||
|
||||
if ((S_ISCHR(sp->st_mode) ||
|
||||
S_ISBLK(sp->st_mode)) &&
|
||||
devstrlen < DEVSTR_HEX_LEN) {
|
||||
if (minor(sp->st_rdev) > 255 ||
|
||||
minor(sp->st_rdev) < 0)
|
||||
devstrlen = DEVSTR_HEX_LEN;
|
||||
else
|
||||
devstrlen = DEVSTR_LEN;
|
||||
if (S_ISCHR(sp->st_mode) ||
|
||||
S_ISBLK(sp->st_mode)) {
|
||||
sizelen = snprintf(NULL, 0,
|
||||
"%#jx", (uintmax_t)sp->st_rdev);
|
||||
if (d.s_size < sizelen)
|
||||
d.s_size = sizelen;
|
||||
}
|
||||
|
||||
if (f_flags) {
|
||||
@ -837,23 +835,16 @@ label_out:
|
||||
d.maxlen = maxlen;
|
||||
if (needstats) {
|
||||
d.btotal = btotal;
|
||||
(void)snprintf(buf, sizeof(buf), "%lu", maxblock);
|
||||
d.s_block = strlen(buf);
|
||||
d.s_block = snprintf(NULL, 0, "%lu", maxblock);
|
||||
d.s_flags = maxflags;
|
||||
d.s_label = maxlabelstr;
|
||||
d.s_group = maxgroup;
|
||||
(void)snprintf(buf, sizeof(buf), "%lu", maxinode);
|
||||
d.s_inode = strlen(buf);
|
||||
(void)snprintf(buf, sizeof(buf), "%lu", maxnlink);
|
||||
d.s_nlink = strlen(buf);
|
||||
if (f_humanval)
|
||||
d.s_size = HUMANVALSTR_LEN;
|
||||
else {
|
||||
(void)snprintf(buf, sizeof(buf), "%ju", maxsize);
|
||||
d.s_size = strlen(buf);
|
||||
}
|
||||
if (d.s_size < devstrlen)
|
||||
d.s_size = devstrlen;
|
||||
d.s_inode = snprintf(NULL, 0, "%lu", maxinode);
|
||||
d.s_nlink = snprintf(NULL, 0, "%lu", maxnlink);
|
||||
sizelen = f_humanval ? HUMANVALSTR_LEN :
|
||||
snprintf(NULL, 0, "%ju", maxsize);
|
||||
if (d.s_size < sizelen)
|
||||
d.s_size = sizelen;
|
||||
d.s_user = maxuser;
|
||||
}
|
||||
printfcn(&d);
|
||||
|
@ -36,8 +36,6 @@
|
||||
#define NO_PRINT 1
|
||||
|
||||
#define HUMANVALSTR_LEN 5
|
||||
#define DEVSTR_LEN 8
|
||||
#define DEVSTR_HEX_LEN 15
|
||||
|
||||
extern long blocksize; /* block size units */
|
||||
|
||||
|
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <langinfo.h>
|
||||
#include <libutil.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -351,16 +352,8 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
|
||||
static void
|
||||
printdev(size_t width, dev_t dev)
|
||||
{
|
||||
char buf[DEVSTR_HEX_LEN + 1];
|
||||
|
||||
if (minor(dev) > 255 || minor(dev) < 0)
|
||||
(void)snprintf(buf, sizeof(buf), "%3d, 0x%08x",
|
||||
major(dev), (u_int)minor(dev));
|
||||
else
|
||||
(void)snprintf(buf, sizeof(buf), "%3d, %3d",
|
||||
major(dev), minor(dev));
|
||||
|
||||
(void)printf("%*s ", (u_int)width, buf);
|
||||
(void)printf("%#*jx ", (u_int)width, (uintmax_t)dev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -39,63 +39,52 @@ extern fixpt_t ccpu;
|
||||
extern int cflag, eval, fscale, nlistread, rawcpu;
|
||||
extern unsigned long mempages;
|
||||
extern time_t now;
|
||||
extern int showthreads, sumrusage, termwidth, totwidth;
|
||||
extern int showthreads, sumrusage, termwidth;
|
||||
extern STAILQ_HEAD(velisthead, varent) varlist;
|
||||
|
||||
__BEGIN_DECLS
|
||||
void arguments(KINFO *, VARENT *);
|
||||
void command(KINFO *, VARENT *);
|
||||
void cputime(KINFO *, VARENT *);
|
||||
char *arguments(KINFO *, VARENT *);
|
||||
char *command(KINFO *, VARENT *);
|
||||
char *cputime(KINFO *, VARENT *);
|
||||
int donlist(void);
|
||||
void elapsed(KINFO *, VARENT *);
|
||||
void elapseds(KINFO *, VARENT *);
|
||||
void emulname(KINFO *, VARENT *);
|
||||
char *elapsed(KINFO *, VARENT *);
|
||||
char *elapseds(KINFO *, VARENT *);
|
||||
char *emulname(KINFO *, VARENT *);
|
||||
VARENT *find_varentry(VAR *);
|
||||
const char *fmt_argv(char **, char *, size_t);
|
||||
double getpcpu(const KINFO *);
|
||||
void kvar(KINFO *, VARENT *);
|
||||
void label(KINFO *, VARENT *);
|
||||
void loginclass(KINFO *, VARENT *);
|
||||
void logname(KINFO *, VARENT *);
|
||||
void longtname(KINFO *, VARENT *);
|
||||
void lstarted(KINFO *, VARENT *);
|
||||
void maxrss(KINFO *, VARENT *);
|
||||
void lockname(KINFO *, VARENT *);
|
||||
void mwchan(KINFO *, VARENT *);
|
||||
void nwchan(KINFO *, VARENT *);
|
||||
void pagein(KINFO *, VARENT *);
|
||||
char *kvar(KINFO *, VARENT *);
|
||||
char *label(KINFO *, VARENT *);
|
||||
char *loginclass(KINFO *, VARENT *);
|
||||
char *logname(KINFO *, VARENT *);
|
||||
char *longtname(KINFO *, VARENT *);
|
||||
char *lstarted(KINFO *, VARENT *);
|
||||
char *maxrss(KINFO *, VARENT *);
|
||||
char *lockname(KINFO *, VARENT *);
|
||||
char *mwchan(KINFO *, VARENT *);
|
||||
char *nwchan(KINFO *, VARENT *);
|
||||
char *pagein(KINFO *, VARENT *);
|
||||
void parsefmt(const char *, int);
|
||||
void pcpu(KINFO *, VARENT *);
|
||||
void pmem(KINFO *, VARENT *);
|
||||
void pri(KINFO *, VARENT *);
|
||||
char *pcpu(KINFO *, VARENT *);
|
||||
char *pmem(KINFO *, VARENT *);
|
||||
char *pri(KINFO *, VARENT *);
|
||||
void printheader(void);
|
||||
void priorityr(KINFO *, VARENT *);
|
||||
void egroupname(KINFO *, VARENT *);
|
||||
void rgroupname(KINFO *, VARENT *);
|
||||
void runame(KINFO *, VARENT *);
|
||||
void rvar(KINFO *, VARENT *);
|
||||
int s_comm(KINFO *);
|
||||
int s_cputime(KINFO *);
|
||||
int s_label(KINFO *);
|
||||
int s_loginclass(KINFO *);
|
||||
int s_logname(KINFO *);
|
||||
int s_egroupname(KINFO *);
|
||||
int s_rgroupname(KINFO *);
|
||||
int s_runame(KINFO *);
|
||||
int s_systime(KINFO *);
|
||||
int s_uname(KINFO *);
|
||||
int s_usertime(KINFO *);
|
||||
char *priorityr(KINFO *, VARENT *);
|
||||
char *egroupname(KINFO *, VARENT *);
|
||||
char *rgroupname(KINFO *, VARENT *);
|
||||
char *runame(KINFO *, VARENT *);
|
||||
char *rvar(KINFO *, VARENT *);
|
||||
void showkey(void);
|
||||
void started(KINFO *, VARENT *);
|
||||
void state(KINFO *, VARENT *);
|
||||
void systime(KINFO *, VARENT *);
|
||||
void tdev(KINFO *, VARENT *);
|
||||
void tdnam(KINFO *, VARENT *);
|
||||
void tname(KINFO *, VARENT *);
|
||||
void ucomm(KINFO *, VARENT *);
|
||||
void uname(KINFO *, VARENT *);
|
||||
void upr(KINFO *, VARENT *);
|
||||
void usertime(KINFO *, VARENT *);
|
||||
void vsize(KINFO *, VARENT *);
|
||||
void wchan(KINFO *, VARENT *);
|
||||
char *started(KINFO *, VARENT *);
|
||||
char *state(KINFO *, VARENT *);
|
||||
char *systime(KINFO *, VARENT *);
|
||||
char *tdev(KINFO *, VARENT *);
|
||||
char *tdnam(KINFO *, VARENT *);
|
||||
char *tname(KINFO *, VARENT *);
|
||||
char *ucomm(KINFO *, VARENT *);
|
||||
char *uname(KINFO *, VARENT *);
|
||||
char *upr(KINFO *, VARENT *);
|
||||
char *usertime(KINFO *, VARENT *);
|
||||
char *vsize(KINFO *, VARENT *);
|
||||
char *wchan(KINFO *, VARENT *);
|
||||
__END_DECLS
|
||||
|
262
bin/ps/keyword.c
262
bin/ps/keyword.c
@ -57,178 +57,116 @@ static int vcmp(const void *, const void *);
|
||||
#define KOFF(x) offsetof(struct kinfo_proc, x)
|
||||
#define ROFF(x) offsetof(struct rusage, x)
|
||||
|
||||
#define EMULLEN 13 /* enough for "FreeBSD ELF32" */
|
||||
#define LWPFMT "d"
|
||||
#define LWPLEN 6
|
||||
#define NLWPFMT "d"
|
||||
#define NLWPLEN 4
|
||||
#define UIDFMT "u"
|
||||
#define UIDLEN 5
|
||||
#define PIDFMT "d"
|
||||
#define PIDLEN 5
|
||||
#define USERLEN (MAXLOGNAME - 1)
|
||||
|
||||
/* PLEASE KEEP THE TABLE BELOW SORTED ALPHABETICALLY!!! */
|
||||
static VAR var[] = {
|
||||
{"%cpu", "%CPU", NULL, 0, pcpu, NULL, 5, 0, CHAR, NULL, 0},
|
||||
{"%mem", "%MEM", NULL, 0, pmem, NULL, 4, 0, CHAR, NULL, 0},
|
||||
{"acflag", "ACFLG", NULL, 0, kvar, NULL, 3, KOFF(ki_acflag), USHORT,
|
||||
"x", 0},
|
||||
{"acflg", "", "acflag", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"args", "COMMAND", NULL, COMM|LJUST|USER, arguments, NULL, 16, 0,
|
||||
{"%cpu", "%CPU", NULL, 0, pcpu, 0, CHAR, NULL, 0},
|
||||
{"%mem", "%MEM", NULL, 0, pmem, 0, CHAR, NULL, 0},
|
||||
{"acflag", "ACFLG", NULL, 0, kvar, KOFF(ki_acflag), USHORT, "x", 0},
|
||||
{"acflg", "", "acflag", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"args", "COMMAND", NULL, COMM|LJUST|USER, arguments, 0,
|
||||
CHAR, NULL, 0},
|
||||
{"blocked", "", "sigmask", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"caught", "", "sigcatch", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"class", "CLASS", NULL, LJUST, loginclass, s_loginclass,
|
||||
MAXLOGNAME-1, 0, CHAR, NULL, 0},
|
||||
{"comm", "COMMAND", NULL, LJUST, ucomm, s_comm,
|
||||
COMMLEN + TDNAMLEN + 1, 0, CHAR, NULL, 0},
|
||||
{"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16, 0,
|
||||
{"blocked", "", "sigmask", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"caught", "", "sigcatch", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"class", "CLASS", NULL, LJUST, loginclass, 0, CHAR, NULL, 0},
|
||||
{"comm", "COMMAND", NULL, LJUST, ucomm, 0, CHAR, NULL, 0},
|
||||
{"command", "COMMAND", NULL, COMM|LJUST|USER, command, 0,
|
||||
CHAR, NULL, 0},
|
||||
{"cpu", "CPU", NULL, 0, kvar, NULL, 3, KOFF(ki_estcpu), UINT, "d",
|
||||
0},
|
||||
{"cputime", "", "time", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"egid", "", "gid", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"egroup", "", "group", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"emul", "EMUL", NULL, LJUST, emulname, NULL, EMULLEN, 0, CHAR,
|
||||
NULL, 0},
|
||||
{"etime", "ELAPSED", NULL, USER, elapsed, NULL, 12, 0, CHAR, NULL, 0},
|
||||
{"etimes", "ELAPSED", NULL, USER, elapseds, NULL, 12, 0, CHAR, NULL, 0},
|
||||
{"euid", "", "uid", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"f", "F", NULL, 0, kvar, NULL, 8, KOFF(ki_flag), INT, "x", 0},
|
||||
{"flags", "", "f", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"gid", "GID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_groups),
|
||||
UINT, UIDFMT, 0},
|
||||
{"group", "GROUP", NULL, LJUST, egroupname, s_egroupname,
|
||||
USERLEN, 0, CHAR, NULL, 0},
|
||||
{"ignored", "", "sigignore", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"inblk", "INBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_inblock), LONG,
|
||||
"ld", 0},
|
||||
{"inblock", "", "inblk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"jid", "JID", NULL, 0, kvar, NULL, 6, KOFF(ki_jid), INT, "d", 0},
|
||||
{"jobc", "JOBC", NULL, 0, kvar, NULL, 4, KOFF(ki_jobc), SHORT, "d",
|
||||
0},
|
||||
{"ktrace", "KTRACE", NULL, 0, kvar, NULL, 8, KOFF(ki_traceflag), INT,
|
||||
"x", 0},
|
||||
{"label", "LABEL", NULL, LJUST, label, s_label, SHRT_MAX, 0, CHAR,
|
||||
NULL, 0},
|
||||
{"lim", "LIM", NULL, 0, maxrss, NULL, 5, 0, CHAR, NULL, 0},
|
||||
{"lockname", "LOCK", NULL, LJUST, lockname, NULL, 6, 0, CHAR, NULL,
|
||||
0},
|
||||
{"login", "LOGIN", NULL, LJUST, logname, s_logname, MAXLOGNAME-1,
|
||||
0, CHAR, NULL, 0},
|
||||
{"logname", "", "login", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"lstart", "STARTED", NULL, LJUST|USER, lstarted, NULL, 28, 0, CHAR,
|
||||
NULL, 0},
|
||||
{"lwp", "LWP", NULL, 0, kvar, NULL, LWPLEN, KOFF(ki_tid), UINT,
|
||||
LWPFMT, 0},
|
||||
{"majflt", "MAJFLT", NULL, USER, rvar, NULL, 4, ROFF(ru_majflt),
|
||||
LONG, "ld", 0},
|
||||
{"minflt", "MINFLT", NULL, USER, rvar, NULL, 4, ROFF(ru_minflt),
|
||||
LONG, "ld", 0},
|
||||
{"msgrcv", "MSGRCV", NULL, USER, rvar, NULL, 4, ROFF(ru_msgrcv),
|
||||
LONG, "ld", 0},
|
||||
{"msgsnd", "MSGSND", NULL, USER, rvar, NULL, 4, ROFF(ru_msgsnd),
|
||||
LONG, "ld", 0},
|
||||
{"mwchan", "MWCHAN", NULL, LJUST, mwchan, NULL, 6, 0, CHAR, NULL, 0},
|
||||
{"ni", "", "nice", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"nice", "NI", NULL, 0, kvar, NULL, 2, KOFF(ki_nice), CHAR, "d",
|
||||
0},
|
||||
{"nivcsw", "NIVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nivcsw),
|
||||
LONG, "ld", 0},
|
||||
{"nlwp", "NLWP", NULL, 0, kvar, NULL, NLWPLEN, KOFF(ki_numthreads),
|
||||
UINT, NLWPFMT, 0},
|
||||
{"nsignals", "", "nsigs", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"nsigs", "NSIGS", NULL, USER, rvar, NULL, 4, ROFF(ru_nsignals),
|
||||
LONG, "ld", 0},
|
||||
{"nswap", "NSWAP", NULL, USER, rvar, NULL, 4, ROFF(ru_nswap),
|
||||
LONG, "ld", 0},
|
||||
{"nvcsw", "NVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw),
|
||||
LONG, "ld", 0},
|
||||
{"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, sizeof(void *) * 2, 0,
|
||||
CHAR, NULL, 0},
|
||||
{"oublk", "OUBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_oublock),
|
||||
LONG, "ld", 0},
|
||||
{"oublock", "", "oublk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"paddr", "PADDR", NULL, 0, kvar, NULL, sizeof(void *) * 2,
|
||||
KOFF(ki_paddr), KPTR, "lx", 0},
|
||||
{"pagein", "PAGEIN", NULL, USER, pagein, NULL, 6, 0, CHAR, NULL, 0},
|
||||
{"pcpu", "", "%cpu", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"pending", "", "sig", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"pgid", "PGID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_pgid), UINT,
|
||||
PIDFMT, 0},
|
||||
{"pid", "PID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_pid), UINT,
|
||||
PIDFMT, 0},
|
||||
{"pmem", "", "%mem", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"ppid", "PPID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_ppid), UINT,
|
||||
PIDFMT, 0},
|
||||
{"pri", "PRI", NULL, 0, pri, NULL, 3, 0, CHAR, NULL, 0},
|
||||
{"re", "RE", NULL, INF127, kvar, NULL, 3, KOFF(ki_swtime), UINT, "d",
|
||||
0},
|
||||
{"rgid", "RGID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_rgid),
|
||||
UINT, UIDFMT, 0},
|
||||
{"rgroup", "RGROUP", NULL, LJUST, rgroupname, s_rgroupname,
|
||||
USERLEN, 0, CHAR, NULL, 0},
|
||||
{"rss", "RSS", NULL, 0, kvar, NULL, 6, KOFF(ki_rssize), PGTOK, "ld", 0},
|
||||
{"rtprio", "RTPRIO", NULL, 0, priorityr, NULL, 7, KOFF(ki_pri), CHAR,
|
||||
NULL, 0},
|
||||
{"ruid", "RUID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_ruid),
|
||||
UINT, UIDFMT, 0},
|
||||
{"ruser", "RUSER", NULL, LJUST, runame, s_runame, USERLEN,
|
||||
0, CHAR, NULL, 0},
|
||||
{"sid", "SID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_sid), UINT,
|
||||
PIDFMT, 0},
|
||||
{"sig", "PENDING", NULL, 0, kvar, NULL, 8, KOFF(ki_siglist), INT,
|
||||
"x", 0},
|
||||
{"sigcatch", "CAUGHT", NULL, 0, kvar, NULL, 8, KOFF(ki_sigcatch),
|
||||
{"cpu", "CPU", NULL, 0, kvar, KOFF(ki_estcpu), UINT, "d", 0},
|
||||
{"cputime", "", "time", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"egid", "", "gid", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"egroup", "", "group", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"emul", "EMUL", NULL, LJUST, emulname, 0, CHAR, NULL, 0},
|
||||
{"etime", "ELAPSED", NULL, USER, elapsed, 0, CHAR, NULL, 0},
|
||||
{"etimes", "ELAPSED", NULL, USER, elapseds, 0, CHAR, NULL, 0},
|
||||
{"euid", "", "uid", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"f", "F", NULL, 0, kvar, KOFF(ki_flag), INT, "x", 0},
|
||||
{"flags", "", "f", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"gid", "GID", NULL, 0, kvar, KOFF(ki_groups), UINT, UIDFMT, 0},
|
||||
{"group", "GROUP", NULL, LJUST, egroupname, 0, CHAR, NULL, 0},
|
||||
{"ignored", "", "sigignore", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"inblk", "INBLK", NULL, USER, rvar, ROFF(ru_inblock), LONG, "ld", 0},
|
||||
{"inblock", "", "inblk", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"jid", "JID", NULL, 0, kvar, KOFF(ki_jid), INT, "d", 0},
|
||||
{"jobc", "JOBC", NULL, 0, kvar, KOFF(ki_jobc), SHORT, "d", 0},
|
||||
{"ktrace", "KTRACE", NULL, 0, kvar, KOFF(ki_traceflag), INT, "x", 0},
|
||||
{"label", "LABEL", NULL, LJUST, label, 0, CHAR, NULL, 0},
|
||||
{"lim", "LIM", NULL, 0, maxrss, 0, CHAR, NULL, 0},
|
||||
{"lockname", "LOCK", NULL, LJUST, lockname, 0, CHAR, NULL, 0},
|
||||
{"login", "LOGIN", NULL, LJUST, logname, 0, CHAR, NULL, 0},
|
||||
{"logname", "", "login", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"lstart", "STARTED", NULL, LJUST|USER, lstarted, 0, CHAR, NULL, 0},
|
||||
{"lwp", "LWP", NULL, 0, kvar, KOFF(ki_tid), UINT, LWPFMT, 0},
|
||||
{"majflt", "MAJFLT", NULL, USER, rvar, ROFF(ru_majflt), LONG, "ld", 0},
|
||||
{"minflt", "MINFLT", NULL, USER, rvar, ROFF(ru_minflt), LONG, "ld", 0},
|
||||
{"msgrcv", "MSGRCV", NULL, USER, rvar, ROFF(ru_msgrcv), LONG, "ld", 0},
|
||||
{"msgsnd", "MSGSND", NULL, USER, rvar, ROFF(ru_msgsnd), LONG, "ld", 0},
|
||||
{"mwchan", "MWCHAN", NULL, LJUST, mwchan, 0, CHAR, NULL, 0},
|
||||
{"ni", "", "nice", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"nice", "NI", NULL, 0, kvar, KOFF(ki_nice), CHAR, "d", 0},
|
||||
{"nivcsw", "NIVCSW", NULL, USER, rvar, ROFF(ru_nivcsw), LONG, "ld", 0},
|
||||
{"nlwp", "NLWP", NULL, 0, kvar, KOFF(ki_numthreads), UINT, NLWPFMT, 0},
|
||||
{"nsignals", "", "nsigs", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"nsigs", "NSIGS", NULL, USER, rvar, ROFF(ru_nsignals), LONG, "ld", 0},
|
||||
{"nswap", "NSWAP", NULL, USER, rvar, ROFF(ru_nswap), LONG, "ld", 0},
|
||||
{"nvcsw", "NVCSW", NULL, USER, rvar, ROFF(ru_nvcsw), LONG, "ld", 0},
|
||||
{"nwchan", "NWCHAN", NULL, LJUST, nwchan, 0, CHAR, NULL, 0},
|
||||
{"oublk", "OUBLK", NULL, USER, rvar, ROFF(ru_oublock), LONG, "ld", 0},
|
||||
{"oublock", "", "oublk", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"paddr", "PADDR", NULL, 0, kvar, KOFF(ki_paddr), KPTR, "lx", 0},
|
||||
{"pagein", "PAGEIN", NULL, USER, pagein, 0, CHAR, NULL, 0},
|
||||
{"pcpu", "", "%cpu", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"pending", "", "sig", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"pgid", "PGID", NULL, 0, kvar, KOFF(ki_pgid), UINT, PIDFMT, 0},
|
||||
{"pid", "PID", NULL, 0, kvar, KOFF(ki_pid), UINT, PIDFMT, 0},
|
||||
{"pmem", "", "%mem", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"ppid", "PPID", NULL, 0, kvar, KOFF(ki_ppid), UINT, PIDFMT, 0},
|
||||
{"pri", "PRI", NULL, 0, pri, 0, CHAR, NULL, 0},
|
||||
{"re", "RE", NULL, INF127, kvar, KOFF(ki_swtime), UINT, "d", 0},
|
||||
{"rgid", "RGID", NULL, 0, kvar, KOFF(ki_rgid), UINT, UIDFMT, 0},
|
||||
{"rgroup", "RGROUP", NULL, LJUST, rgroupname, 0, CHAR, NULL, 0},
|
||||
{"rss", "RSS", NULL, 0, kvar, KOFF(ki_rssize), PGTOK, "ld", 0},
|
||||
{"rtprio", "RTPRIO", NULL, 0, priorityr, KOFF(ki_pri), CHAR, NULL, 0},
|
||||
{"ruid", "RUID", NULL, 0, kvar, KOFF(ki_ruid), UINT, UIDFMT, 0},
|
||||
{"ruser", "RUSER", NULL, LJUST, runame, 0, CHAR, NULL, 0},
|
||||
{"sid", "SID", NULL, 0, kvar, KOFF(ki_sid), UINT, PIDFMT, 0},
|
||||
{"sig", "PENDING", NULL, 0, kvar, KOFF(ki_siglist), INT, "x", 0},
|
||||
{"sigcatch", "CAUGHT", NULL, 0, kvar, KOFF(ki_sigcatch), UINT, "x", 0},
|
||||
{"sigignore", "IGNORED", NULL, 0, kvar, KOFF(ki_sigignore),
|
||||
UINT, "x", 0},
|
||||
{"sigignore", "IGNORED", NULL, 0, kvar, NULL, 8, KOFF(ki_sigignore),
|
||||
UINT, "x", 0},
|
||||
{"sigmask", "BLOCKED", NULL, 0, kvar, NULL, 8, KOFF(ki_sigmask),
|
||||
UINT, "x", 0},
|
||||
{"sl", "SL", NULL, INF127, kvar, NULL, 3, KOFF(ki_slptime), UINT, "d",
|
||||
0},
|
||||
{"start", "STARTED", NULL, LJUST|USER, started, NULL, 7, 0, CHAR, NULL,
|
||||
0},
|
||||
{"stat", "", "state", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"state", "STAT", NULL, 0, state, NULL, 4, 0, CHAR, NULL, 0},
|
||||
{"svgid", "SVGID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_svgid),
|
||||
UINT, UIDFMT, 0},
|
||||
{"svuid", "SVUID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_svuid),
|
||||
UINT, UIDFMT, 0},
|
||||
{"systime", "SYSTIME", NULL, USER, systime, s_systime, 15, 0, CHAR,
|
||||
NULL, 0},
|
||||
{"tdaddr", "TDADDR", NULL, 0, kvar, NULL, sizeof(void *) * 2,
|
||||
KOFF(ki_tdaddr), KPTR, "lx", 0},
|
||||
{"tdev", "TDEV", NULL, 0, tdev, NULL, 5, 0, CHAR, NULL, 0},
|
||||
{"tdnam", "TDNAM", NULL, LJUST, tdnam, NULL, COMMLEN, 0, CHAR, NULL, 0},
|
||||
{"time", "TIME", NULL, USER, cputime, s_cputime, 15, 0, CHAR,
|
||||
NULL, 0},
|
||||
{"tpgid", "TPGID", NULL, 0, kvar, NULL, 4, KOFF(ki_tpgid), UINT,
|
||||
PIDFMT, 0},
|
||||
{"tsid", "TSID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_tsid), UINT,
|
||||
PIDFMT, 0},
|
||||
{"tsiz", "TSIZ", NULL, 0, kvar, NULL, 4, KOFF(ki_tsize), PGTOK, "ld", 0},
|
||||
{"tt", "TT ", NULL, 0, tname, NULL, 4, 0, CHAR, NULL, 0},
|
||||
{"tty", "TTY", NULL, LJUST, longtname, NULL, 8, 0, CHAR, NULL, 0},
|
||||
{"ucomm", "UCOMM", NULL, LJUST, ucomm, s_comm,
|
||||
COMMLEN + TDNAMLEN + 1, 0, CHAR, NULL, 0},
|
||||
{"uid", "UID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_uid), UINT,
|
||||
UIDFMT, 0},
|
||||
{"upr", "UPR", NULL, 0, upr, NULL, 3, 0, CHAR, NULL, 0},
|
||||
{"uprocp", "UPROCP", NULL, 0, kvar, NULL, sizeof(void *) * 2,
|
||||
KOFF(ki_paddr), KPTR, "lx", 0},
|
||||
{"user", "USER", NULL, LJUST, uname, s_uname, USERLEN, 0, CHAR,
|
||||
NULL, 0},
|
||||
{"usertime", "USERTIME", NULL, USER, usertime, s_usertime, 15, 0,
|
||||
CHAR, NULL, 0},
|
||||
{"usrpri", "", "upr", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"vsize", "", "vsz", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"vsz", "VSZ", NULL, 0, vsize, NULL, 6, 0, CHAR, NULL, 0},
|
||||
{"wchan", "WCHAN", NULL, LJUST, wchan, NULL, 6, 0, CHAR, NULL, 0},
|
||||
{"xstat", "XSTAT", NULL, 0, kvar, NULL, 4, KOFF(ki_xstat), USHORT,
|
||||
"x", 0},
|
||||
{"", NULL, NULL, 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
|
||||
{"sigmask", "BLOCKED", NULL, 0, kvar, KOFF(ki_sigmask), UINT, "x", 0},
|
||||
{"sl", "SL", NULL, INF127, kvar, KOFF(ki_slptime), UINT, "d", 0},
|
||||
{"start", "STARTED", NULL, LJUST|USER, started, 0, CHAR, NULL, 0},
|
||||
{"stat", "", "state", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"state", "STAT", NULL, LJUST, state, 0, CHAR, NULL, 0},
|
||||
{"svgid", "SVGID", NULL, 0, kvar, KOFF(ki_svgid), UINT, UIDFMT, 0},
|
||||
{"svuid", "SVUID", NULL, 0, kvar, KOFF(ki_svuid), UINT, UIDFMT, 0},
|
||||
{"systime", "SYSTIME", NULL, USER, systime, 0, CHAR, NULL, 0},
|
||||
{"tdaddr", "TDADDR", NULL, 0, kvar, KOFF(ki_tdaddr), KPTR, "lx", 0},
|
||||
{"tdev", "TDEV", NULL, 0, tdev, 0, CHAR, NULL, 0},
|
||||
{"tdnam", "TDNAM", NULL, LJUST, tdnam, 0, CHAR, NULL, 0},
|
||||
{"time", "TIME", NULL, USER, cputime, 0, CHAR, NULL, 0},
|
||||
{"tpgid", "TPGID", NULL, 0, kvar, KOFF(ki_tpgid), UINT, PIDFMT, 0},
|
||||
{"tsid", "TSID", NULL, 0, kvar, KOFF(ki_tsid), UINT, PIDFMT, 0},
|
||||
{"tsiz", "TSIZ", NULL, 0, kvar, KOFF(ki_tsize), PGTOK, "ld", 0},
|
||||
{"tt", "TT ", NULL, 0, tname, 0, CHAR, NULL, 0},
|
||||
{"tty", "TTY", NULL, LJUST, longtname, 0, CHAR, NULL, 0},
|
||||
{"ucomm", "UCOMM", NULL, LJUST, ucomm, 0, CHAR, NULL, 0},
|
||||
{"uid", "UID", NULL, 0, kvar, KOFF(ki_uid), UINT, UIDFMT, 0},
|
||||
{"upr", "UPR", NULL, 0, upr, 0, CHAR, NULL, 0},
|
||||
{"uprocp", "UPROCP", NULL, 0, kvar, KOFF(ki_paddr), KPTR, "lx", 0},
|
||||
{"user", "USER", NULL, LJUST, uname, 0, CHAR, NULL, 0},
|
||||
{"usertime", "USERTIME", NULL, USER, usertime, 0, CHAR, NULL, 0},
|
||||
{"usrpri", "", "upr", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"vsize", "", "vsz", 0, NULL, 0, CHAR, NULL, 0},
|
||||
{"vsz", "VSZ", NULL, 0, vsize, 0, CHAR, NULL, 0},
|
||||
{"wchan", "WCHAN", NULL, LJUST, wchan, 0, CHAR, NULL, 0},
|
||||
{"xstat", "XSTAT", NULL, 0, kvar, KOFF(ki_xstat), USHORT, "x", 0},
|
||||
{"", NULL, NULL, 0, NULL, 0, CHAR, NULL, 0},
|
||||
};
|
||||
|
||||
void
|
||||
|
591
bin/ps/print.c
591
bin/ps/print.c
File diff suppressed because it is too large
Load Diff
103
bin/ps/ps.c
103
bin/ps/ps.c
@ -99,14 +99,12 @@ time_t now; /* Current time(3) value */
|
||||
int rawcpu; /* -C */
|
||||
int sumrusage; /* -S */
|
||||
int termwidth; /* Width of the screen (0 == infinity). */
|
||||
int totwidth; /* Calculated-width of requested variables. */
|
||||
int showthreads; /* will threads be shown? */
|
||||
|
||||
struct velisthead varlist = STAILQ_HEAD_INITIALIZER(varlist);
|
||||
|
||||
static int forceuread = DEF_UREAD; /* Do extra work to get u-area. */
|
||||
static kvm_t *kd;
|
||||
static KINFO *kinfo;
|
||||
static int needcomm; /* -o "command" */
|
||||
static int needenv; /* -e */
|
||||
static int needuser; /* -o "user" */
|
||||
@ -139,7 +137,7 @@ static int addelem_tty(struct listinfo *, const char *);
|
||||
static int addelem_uid(struct listinfo *, const char *);
|
||||
static void add_list(struct listinfo *, const char *);
|
||||
static void descendant_sort(KINFO *, int);
|
||||
static void dynsizevars(KINFO *);
|
||||
static void format_output(KINFO *);
|
||||
static void *expand_list(struct listinfo *);
|
||||
static const char *
|
||||
fmt(char **(*)(kvm_t *, const struct kinfo_proc *, int),
|
||||
@ -172,12 +170,13 @@ main(int argc, char *argv[])
|
||||
struct listinfo gidlist, pgrplist, pidlist;
|
||||
struct listinfo ruidlist, sesslist, ttylist, uidlist;
|
||||
struct kinfo_proc *kp;
|
||||
KINFO *next_KINFO;
|
||||
KINFO *kinfo = NULL, *next_KINFO;
|
||||
KINFO_STR *ks;
|
||||
struct varent *vent;
|
||||
struct winsize ws;
|
||||
const char *nlistf, *memf;
|
||||
const char *nlistf, *memf, *fmtstr, *str;
|
||||
char *cols;
|
||||
int all, ch, elem, flag, _fmt, i, lineno;
|
||||
int all, ch, elem, flag, _fmt, i, lineno, linelen, left;
|
||||
int descendancy, nentries, nkept, nselectors;
|
||||
int prtheader, wflag, what, xkeep, xkeep_implied;
|
||||
char errbuf[_POSIX2_LINE_MAX];
|
||||
@ -588,19 +587,16 @@ main(int argc, char *argv[])
|
||||
kp->ki_dsize + kp->ki_ssize;
|
||||
if (needuser)
|
||||
saveuser(next_KINFO);
|
||||
dynsizevars(next_KINFO);
|
||||
nkept++;
|
||||
}
|
||||
}
|
||||
|
||||
sizevars();
|
||||
|
||||
/*
|
||||
* print header
|
||||
*/
|
||||
printheader();
|
||||
if (nkept == 0)
|
||||
if (nkept == 0) {
|
||||
printheader();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* sort proc list
|
||||
@ -613,14 +609,59 @@ main(int argc, char *argv[])
|
||||
if (descendancy)
|
||||
descendant_sort(kinfo, nkept);
|
||||
|
||||
|
||||
/*
|
||||
* For each process, call each variable output function.
|
||||
* Prepare formatted output.
|
||||
*/
|
||||
for (i = 0; i < nkept; i++)
|
||||
format_output(&kinfo[i]);
|
||||
|
||||
/*
|
||||
* Print header.
|
||||
*/
|
||||
printheader();
|
||||
|
||||
/*
|
||||
* Output formatted lines.
|
||||
*/
|
||||
for (i = lineno = 0; i < nkept; i++) {
|
||||
linelen = 0;
|
||||
STAILQ_FOREACH(vent, &varlist, next_ve) {
|
||||
(vent->var->oproc)(&kinfo[i], vent);
|
||||
if (STAILQ_NEXT(vent, next_ve) != NULL)
|
||||
if (vent->var->flag & LJUST)
|
||||
fmtstr = "%-*s";
|
||||
else
|
||||
fmtstr = "%*s";
|
||||
|
||||
ks = STAILQ_FIRST(&kinfo[i].ki_ks);
|
||||
STAILQ_REMOVE_HEAD(&kinfo[i].ki_ks, ks_next);
|
||||
/* Truncate rightmost column if neccessary. */
|
||||
if (STAILQ_NEXT(vent, next_ve) == NULL &&
|
||||
termwidth != UNLIMITED && ks->ks_str != NULL) {
|
||||
left = termwidth - linelen;
|
||||
if (left > 0 && left < (int)strlen(ks->ks_str))
|
||||
ks->ks_str[left] = '\0';
|
||||
}
|
||||
str = ks->ks_str;
|
||||
if (str == NULL)
|
||||
str = "-";
|
||||
/* No padding for the last column, if it's LJUST. */
|
||||
if (STAILQ_NEXT(vent, next_ve) == NULL &&
|
||||
vent->var->flag & LJUST)
|
||||
linelen += printf(fmtstr, 0, str);
|
||||
else
|
||||
linelen += printf(fmtstr, vent->var->width, str);
|
||||
|
||||
if (ks->ks_str != NULL) {
|
||||
free(ks->ks_str);
|
||||
ks->ks_str = NULL;
|
||||
}
|
||||
free(ks);
|
||||
ks = NULL;
|
||||
|
||||
if (STAILQ_NEXT(vent, next_ve) != NULL) {
|
||||
(void)putchar(' ');
|
||||
linelen++;
|
||||
}
|
||||
}
|
||||
(void)putchar('\n');
|
||||
if (prtheader && lineno++ == prtheader - 4) {
|
||||
@ -1078,10 +1119,6 @@ scanvars(void)
|
||||
|
||||
STAILQ_FOREACH(vent, &varlist, next_ve) {
|
||||
v = vent->var;
|
||||
if (v->sproc != NULL) {
|
||||
v->dwidth = v->width;
|
||||
v->width = 0;
|
||||
}
|
||||
if (v->flag & USER)
|
||||
needuser = 1;
|
||||
if (v->flag & COMM)
|
||||
@ -1090,21 +1127,29 @@ scanvars(void)
|
||||
}
|
||||
|
||||
static void
|
||||
dynsizevars(KINFO *ki)
|
||||
format_output(KINFO *ki)
|
||||
{
|
||||
struct varent *vent;
|
||||
VAR *v;
|
||||
int i;
|
||||
KINFO_STR *ks;
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
STAILQ_INIT(&ki->ki_ks);
|
||||
STAILQ_FOREACH(vent, &varlist, next_ve) {
|
||||
v = vent->var;
|
||||
if (v->sproc == NULL)
|
||||
continue;
|
||||
i = (v->sproc)(ki);
|
||||
if (v->width < i)
|
||||
v->width = i;
|
||||
if (v->width > v->dwidth)
|
||||
v->width = v->dwidth;
|
||||
str = (v->oproc)(ki, vent);
|
||||
ks = malloc(sizeof(*ks));
|
||||
if (ks == NULL)
|
||||
errx(1, "malloc failed");
|
||||
ks->ks_str = str;
|
||||
STAILQ_INSERT_TAIL(&ki->ki_ks, ks, ks_next);
|
||||
if (str != NULL) {
|
||||
len = strlen(str);
|
||||
} else
|
||||
len = 1; /* "-" */
|
||||
if (v->width < len)
|
||||
v->width = len;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1120,9 +1165,7 @@ sizevars(void)
|
||||
i = strlen(vent->header);
|
||||
if (v->width < i)
|
||||
v->width = i;
|
||||
totwidth += v->width + 1; /* +1 for space */
|
||||
}
|
||||
totwidth--;
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
17
bin/ps/ps.h
17
bin/ps/ps.h
@ -35,6 +35,11 @@
|
||||
#define UNLIMITED 0 /* unlimited terminal width */
|
||||
enum type { CHAR, UCHAR, SHORT, USHORT, INT, UINT, LONG, ULONG, KPTR, PGTOK };
|
||||
|
||||
typedef struct kinfo_str {
|
||||
STAILQ_ENTRY(kinfo_str) ks_next;
|
||||
char *ks_str; /* formatted string */
|
||||
} KINFO_STR;
|
||||
|
||||
typedef struct kinfo {
|
||||
struct kinfo_proc *ki_p; /* kinfo_proc structure */
|
||||
char *ki_args; /* exec args */
|
||||
@ -46,6 +51,7 @@ typedef struct kinfo {
|
||||
int level; /* used in decendant_sort() */
|
||||
char *prefix; /* calculated in decendant_sort() */
|
||||
} ki_d;
|
||||
STAILQ_HEAD(, kinfo_str) ki_ks;
|
||||
} KINFO;
|
||||
|
||||
/* Variables. */
|
||||
@ -65,10 +71,7 @@ typedef struct var {
|
||||
#define INF127 0x10 /* values >127 displayed as 127 */
|
||||
u_int flag;
|
||||
/* output routine */
|
||||
void (*oproc)(struct kinfo *, struct varent *);
|
||||
/* sizing routine */
|
||||
int (*sproc)(struct kinfo *);
|
||||
short width; /* printing width */
|
||||
char *(*oproc)(struct kinfo *, struct varent *);
|
||||
/*
|
||||
* The following (optional) elements are hooks for passing information
|
||||
* to the generic output routine pvar (which prints simple elements
|
||||
@ -77,10 +80,8 @@ typedef struct var {
|
||||
size_t off; /* offset in structure */
|
||||
enum type type; /* type of element */
|
||||
const char *fmt; /* printf format */
|
||||
short dwidth; /* dynamic printing width */
|
||||
/*
|
||||
* glue to link selected fields together
|
||||
*/
|
||||
|
||||
short width; /* calculated width */
|
||||
} VAR;
|
||||
|
||||
#include "extern.h"
|
||||
|
@ -467,7 +467,6 @@ change_one(zfs_handle_t *zhp, void *data)
|
||||
* This is necessary when the original mountpoint
|
||||
* is legacy or none.
|
||||
*/
|
||||
ASSERT(!clp->cl_alldependents);
|
||||
verify(uu_list_insert_before(clp->cl_list,
|
||||
uu_list_first(clp->cl_list), cn) == 0);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* A list of symbols which need munging is obtained as follows:
|
||||
*
|
||||
* nm libssh.a | awk '/[0-9a-z] [A-Z] / && $3 !~ /^ssh_/ { print "#define" $3 "\t\tssh_" $3 }'
|
||||
* nm libssh.a | awk '/[0-9a-z] [A-Z] / && $3 !~ /^ssh_/ { print "#define " $3 "\t\tssh_" $3 }'
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -58,6 +58,7 @@
|
||||
#define buffer_get_int64 ssh_buffer_get_int64
|
||||
#define buffer_get_int64_ret ssh_buffer_get_int64_ret
|
||||
#define buffer_get_int_ret ssh_buffer_get_int_ret
|
||||
#define buffer_get_max_len ssh_buffer_get_max_len
|
||||
#define buffer_get_ret ssh_buffer_get_ret
|
||||
#define buffer_get_short ssh_buffer_get_short
|
||||
#define buffer_get_short_ret ssh_buffer_get_short_ret
|
||||
@ -139,6 +140,7 @@
|
||||
#define channel_send_window_changes ssh_channel_send_window_changes
|
||||
#define channel_set_af ssh_channel_set_af
|
||||
#define channel_set_fds ssh_channel_set_fds
|
||||
#define channel_set_hpn ssh_channel_set_hpn
|
||||
#define channel_setup_local_fwd_listener ssh_channel_setup_local_fwd_listener
|
||||
#define channel_setup_remote_fwd_listener ssh_channel_setup_remote_fwd_listener
|
||||
#define channel_still_open ssh_channel_still_open
|
||||
@ -438,6 +440,7 @@
|
||||
#define set_nonblock ssh_set_nonblock
|
||||
#define shadow_pw ssh_shadow_pw
|
||||
#define sigdie ssh_sigdie
|
||||
#define sock_get_rcvbuf ssh_sock_get_rcvbuf
|
||||
#define sock_set_v6only ssh_sock_set_v6only
|
||||
#define ssh1_3des_iv ssh_ssh1_3des_iv
|
||||
#define start_progress_meter ssh_start_progress_meter
|
||||
|
@ -8,10 +8,10 @@
|
||||
# NB: device-name is shorthand for 'match device-name'
|
||||
|
||||
options {
|
||||
# Each directory directive adds a directory the list of directories
|
||||
# that we scan for files. Files are read-in in the order that they
|
||||
# are returned from readdir(3). The rule-sets are combined to
|
||||
# create a DFA that's used to match events to actions.
|
||||
# Each "directory" directive adds a directory to the list of
|
||||
# directories that we scan for files. Files are loaded in the order
|
||||
# that they are returned from readdir(3). The rule-sets are combined
|
||||
# to create a DFA that's used to match events to actions.
|
||||
directory "/etc/devd";
|
||||
directory "/usr/local/etc/devd";
|
||||
pid-file "/var/run/devd.pid";
|
||||
@ -32,8 +32,8 @@ options {
|
||||
# script is called pccard_ether.
|
||||
#
|
||||
# NB: DETACH events are ignored; the kernel should handle all cleanup
|
||||
# (routes, arp cache) if you need to do something beware of races
|
||||
# against immediate create of a device w/ the same name; e.g.
|
||||
# (routes, arp cache). Beware of races against immediate create
|
||||
# of a device with the same name; e.g.
|
||||
# ifconfig bridge0 destroy; ifconfig bridge0 create
|
||||
#
|
||||
notify 0 {
|
||||
@ -43,7 +43,7 @@ notify 0 {
|
||||
};
|
||||
|
||||
#
|
||||
# Try to start dhclient on Ethernet like interfaces when the link comes
|
||||
# Try to start dhclient on Ethernet-like interfaces when the link comes
|
||||
# up. Only devices that are configured to support DHCP will actually
|
||||
# run it. No link down rule exists because dhclient automatically exits
|
||||
# when the link goes down.
|
||||
@ -87,7 +87,7 @@ detach 100 {
|
||||
device-name "ed50";
|
||||
};
|
||||
|
||||
# When a USB Bluetooth dongle appears activate it
|
||||
# When a USB Bluetooth dongle appears, activate it
|
||||
attach 100 {
|
||||
device-name "ubt[0-9]+";
|
||||
action "/etc/rc.d/bluetooth quietstart $device-name";
|
||||
@ -125,7 +125,7 @@ detach 100 {
|
||||
};
|
||||
|
||||
# Firmware download into the ActiveWire board. After the firmware download is
|
||||
# done the device detaches and reappears as something new and shiny
|
||||
# done, the device detaches and reappears as something new and shiny
|
||||
# automatically.
|
||||
attach 100 {
|
||||
match "vendor" "0x0854";
|
||||
@ -265,12 +265,11 @@ notify 10 {
|
||||
|
||||
/* EXAMPLES TO END OF FILE
|
||||
|
||||
# The following might be an example of something that a vendor might
|
||||
# install if you were to add their device. This might reside in
|
||||
# /usr/local/etc/devd/deqna.conf. A deqna is, in this hypothetical
|
||||
# example, a pccard ethernet-like device. Students of history may
|
||||
# know other devices by this name, and will get the in-jokes in this
|
||||
# entry.
|
||||
# An example of something that a vendor might install if you were to
|
||||
# add their device. This might reside in /usr/local/etc/devd/deqna.conf.
|
||||
# A deqna is, in this hypothetical example, a pccard ethernet-like device.
|
||||
# Students of history may know other devices by this name, and will get
|
||||
# the in-jokes in this entry.
|
||||
nomatch 10 {
|
||||
match "bus" "pccard[0-9]+";
|
||||
match "manufacturer" "0x1234";
|
||||
@ -288,7 +287,7 @@ detach 10 {
|
||||
|
||||
# Examples of notify hooks. A notify is a generic way for a kernel
|
||||
# subsystem to send event notification to userland.
|
||||
#
|
||||
|
||||
# Here are some examples of ACPI notify handlers. ACPI subsystems that
|
||||
# generate notifies include the AC adapter, power/sleep buttons,
|
||||
# control method batteries, lid switch, and thermal zones.
|
||||
@ -316,7 +315,7 @@ notify 10 {
|
||||
};
|
||||
|
||||
# This example works around a memory leak in PostgreSQL, restarting
|
||||
# it when "user:pgsql:swap:devctl=1G" rctl(8) rule gets triggered.
|
||||
# it when the "user:pgsql:swap:devctl=1G" rctl(8) rule gets triggered.
|
||||
notify 0 {
|
||||
match "system" "RCTL";
|
||||
match "rule" "user:70:swap:.*";
|
||||
|
@ -297,6 +297,10 @@ dhcpif()
|
||||
local _tmpargs _arg
|
||||
_tmpargs=`_ifconfig_getargs $1`
|
||||
|
||||
if noafif $1; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
for _arg in $_tmpargs; do
|
||||
case $_arg in
|
||||
[Dd][Hh][Cc][Pp])
|
||||
@ -322,6 +326,10 @@ syncdhcpif()
|
||||
local _tmpargs _arg
|
||||
_tmpargs=`_ifconfig_getargs $1`
|
||||
|
||||
if noafif $1; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
for _arg in $_tmpargs; do
|
||||
case $_arg in
|
||||
[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
|
||||
|
@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
@ -60,8 +61,8 @@ devname_r(dev_t dev, mode_t type, char *buf, int len)
|
||||
}
|
||||
|
||||
/* Finally just format it */
|
||||
snprintf(buf, len, "#%c:%d:0x%x",
|
||||
S_ISCHR(type) ? 'C' : 'B', major(dev), minor(dev));
|
||||
snprintf(buf, len, "#%c:%#jx",
|
||||
S_ISCHR(type) ? 'C' : 'B', (uintmax_t)dev);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#include "usbhid.h"
|
||||
#include "usbvar.h"
|
||||
|
||||
int32_t
|
||||
hid_get_data(const void *p, const hid_item_t *h)
|
||||
@ -114,3 +117,27 @@ hid_set_data(void *p, const hid_item_t *h, int32_t data)
|
||||
buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) |
|
||||
((data >> (i*8)) & 0xff);
|
||||
}
|
||||
|
||||
int
|
||||
hid_get_report(int fd, enum hid_kind k, unsigned char *data, unsigned int size)
|
||||
{
|
||||
struct usb_gen_descriptor ugd;
|
||||
|
||||
memset(&ugd, 0, sizeof(ugd));
|
||||
ugd.ugd_data = hid_pass_ptr(data);
|
||||
ugd.ugd_maxlen = size;
|
||||
ugd.ugd_report_type = k + 1;
|
||||
return (ioctl(fd, USB_GET_REPORT, &ugd));
|
||||
}
|
||||
|
||||
int
|
||||
hid_set_report(int fd, enum hid_kind k, unsigned char *data, unsigned int size)
|
||||
{
|
||||
struct usb_gen_descriptor ugd;
|
||||
|
||||
memset(&ugd, 0, sizeof(ugd));
|
||||
ugd.ugd_data = hid_pass_ptr(data);
|
||||
ugd.ugd_maxlen = size;
|
||||
ugd.ugd_report_type = k + 1;
|
||||
return (ioctl(fd, USB_SET_REPORT, &ugd));
|
||||
}
|
||||
|
@ -43,10 +43,11 @@ __FBSDID("$FreeBSD$");
|
||||
#define MAXUSAGE 100
|
||||
#define MAXPUSH 4
|
||||
#define MAXID 64
|
||||
#define ITEMTYPES 3
|
||||
|
||||
struct hid_pos_data {
|
||||
int32_t rid;
|
||||
uint32_t pos;
|
||||
uint32_t pos[ITEMTYPES];
|
||||
};
|
||||
|
||||
struct hid_data {
|
||||
@ -55,6 +56,7 @@ struct hid_data {
|
||||
const uint8_t *p;
|
||||
struct hid_item cur[MAXPUSH];
|
||||
struct hid_pos_data last_pos[MAXID];
|
||||
uint32_t pos[ITEMTYPES];
|
||||
int32_t usages_min[MAXUSAGE];
|
||||
int32_t usages_max[MAXUSAGE];
|
||||
int32_t usage_last; /* last seen usage */
|
||||
@ -92,7 +94,7 @@ hid_clear_local(hid_item_t *c)
|
||||
static void
|
||||
hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t i, j;
|
||||
|
||||
/* check for same report ID - optimise */
|
||||
|
||||
@ -113,7 +115,8 @@ hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID)
|
||||
}
|
||||
if (i != MAXID) {
|
||||
s->last_pos[i].rid = c->report_ID;
|
||||
s->last_pos[i].pos = c->pos;
|
||||
for (j = 0; j < ITEMTYPES; j++)
|
||||
s->last_pos[i].pos[j] = s->pos[j];
|
||||
}
|
||||
|
||||
/* store next report ID */
|
||||
@ -134,9 +137,12 @@ hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID)
|
||||
}
|
||||
if (i != MAXID) {
|
||||
s->last_pos[i].rid = next_rID;
|
||||
c->pos = s->last_pos[i].pos;
|
||||
} else
|
||||
c->pos = 0; /* Out of RID entries. */
|
||||
for (j = 0; j < ITEMTYPES; j++)
|
||||
s->pos[j] = s->last_pos[i].pos[j];
|
||||
} else {
|
||||
for (j = 0; j < ITEMTYPES; j++)
|
||||
s->pos[j] = 0; /* Out of RID entries. */
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
@ -206,7 +212,6 @@ hid_get_item(hid_data_t s, hid_item_t *h)
|
||||
{
|
||||
hid_item_t *c;
|
||||
unsigned int bTag, bType, bSize;
|
||||
uint32_t oldpos;
|
||||
int32_t mask;
|
||||
int32_t dval;
|
||||
|
||||
@ -240,7 +245,8 @@ hid_get_item(hid_data_t s, hid_item_t *h)
|
||||
*/
|
||||
if (s->kindset & (1 << c->kind)) {
|
||||
*h = *c;
|
||||
c->pos += c->report_size * c->report_count;
|
||||
h->pos = s->pos[c->kind];
|
||||
s->pos[c->kind] += c->report_size * c->report_count;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
@ -406,14 +412,10 @@ hid_get_item(hid_data_t s, hid_item_t *h)
|
||||
case 11: /* Pop */
|
||||
s->pushlevel --;
|
||||
if (s->pushlevel < MAXPUSH) {
|
||||
/* preserve position */
|
||||
oldpos = c->pos;
|
||||
c = &s->cur[s->pushlevel];
|
||||
/* restore size and count */
|
||||
s->loc_size = c->report_size;
|
||||
s->loc_count = c->report_count;
|
||||
/* set default item location */
|
||||
c->pos = oldpos;
|
||||
c->report_size = 0;
|
||||
c->report_count = 0;
|
||||
}
|
||||
|
@ -44,7 +44,9 @@
|
||||
.Nm hid_usage_in_page ,
|
||||
.Nm hid_init ,
|
||||
.Nm hid_get_data ,
|
||||
.Nm hid_set_data
|
||||
.Nm hid_set_data ,
|
||||
.Nm hid_get_report ,
|
||||
.Nm hid_set_report
|
||||
.Nd USB HID access routines
|
||||
.Sh LIBRARY
|
||||
.Lb libusbhid
|
||||
@ -84,6 +86,10 @@
|
||||
.Fn hid_get_data "const void *data" "const hid_item_t *h"
|
||||
.Ft void
|
||||
.Fn hid_set_data "void *buf" "const hid_item_t *h" "int data"
|
||||
.Ft int
|
||||
.Fn hid_get_report "int fd" "enum hid_kind k" "unsigned char *data" "unsigned int size"
|
||||
.Ft int
|
||||
.Fn hid_set_report "int fd" "enum hid_kind k" "unsigned char *data" "unsigned int size"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
@ -105,6 +111,14 @@ Synchronous HID operation can be enabled or disabled by a call to
|
||||
If the second argument is zero synchronous HID operation is disabled.
|
||||
Else synchronous HID operation is enabled.
|
||||
The function returns a negative value on failure.
|
||||
.Pp
|
||||
.Fn hid_get_report
|
||||
and
|
||||
.Fn hid_set_report
|
||||
functions allow to synchronously get and set specific report if device
|
||||
supports it.
|
||||
For devices with multiple report IDs, wanted ID should be provided in the
|
||||
first byte of the buffer for both get and set.
|
||||
.Ss Descriptor Functions
|
||||
The report descriptor ID can be obtained by calling
|
||||
.Fn hid_get_report_id .
|
||||
|
@ -76,6 +76,7 @@ typedef struct hid_item {
|
||||
|
||||
#define HID_PAGE(u) (((u) >> 16) & 0xffff)
|
||||
#define HID_USAGE(u) ((u) & 0xffff)
|
||||
#define HID_HAS_GET_SET_REPORT 1
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@ -104,5 +105,9 @@ int hid_parse_usage_page(const char *name);
|
||||
/* Extracting/insertion of data, data.c: */
|
||||
int32_t hid_get_data(const void *p, const hid_item_t *h);
|
||||
void hid_set_data(void *p, const hid_item_t *h, int32_t data);
|
||||
int hid_get_report(int fd, enum hid_kind k,
|
||||
unsigned char *data, unsigned int size);
|
||||
int hid_set_report(int fd, enum hid_kind k,
|
||||
unsigned char *data, unsigned int size);
|
||||
|
||||
__END_DECLS
|
||||
|
@ -126,12 +126,10 @@ printstat(const char *cp, ino_t inum, union dinode *dp)
|
||||
puts("regular file");
|
||||
break;
|
||||
case IFBLK:
|
||||
printf("block special (%d,%d)",
|
||||
major(DIP(dp, di_rdev)), minor(DIP(dp, di_rdev)));
|
||||
printf("block special (%#jx)", (uintmax_t)DIP(dp, di_rdev));
|
||||
break;
|
||||
case IFCHR:
|
||||
printf("character special (%d,%d)",
|
||||
major(DIP(dp, di_rdev)), minor(DIP(dp, di_rdev)));
|
||||
printf("character special (%#jx)", DIP(dp, di_rdev));
|
||||
break;
|
||||
case IFLNK:
|
||||
fputs("symlink",stdout);
|
||||
|
@ -63,6 +63,7 @@ checksum <algorithm>
|
||||
compression <algorithm>
|
||||
timeout <seconds>
|
||||
exec <path>
|
||||
metaflush "on" | "off"
|
||||
|
||||
on <node> {
|
||||
# Node section
|
||||
@ -85,12 +86,14 @@ resource <name> {
|
||||
local <path>
|
||||
timeout <seconds>
|
||||
exec <path>
|
||||
metaflush "on" | "off"
|
||||
|
||||
on <node> {
|
||||
# Resource-node section
|
||||
name <name>
|
||||
# Required
|
||||
local <path>
|
||||
metaflush "on" | "off"
|
||||
# Required
|
||||
remote <addr>
|
||||
source <addr>
|
||||
@ -100,6 +103,7 @@ resource <name> {
|
||||
name <name>
|
||||
# Required
|
||||
local <path>
|
||||
metaflush "on" | "off"
|
||||
# Required
|
||||
remote <addr>
|
||||
source <addr>
|
||||
@ -318,6 +322,25 @@ It can be one of:
|
||||
.Ar secondary ,
|
||||
.Ar primary .
|
||||
.Pp
|
||||
.It Ic metaflush on | off
|
||||
.Pp
|
||||
When set to
|
||||
.Va on ,
|
||||
flush write cache of the local provider after every metadata (activemap) update.
|
||||
Flushing write cache ensures that provider will not reorder writes and that
|
||||
metadata will be properly updated before real data is stored.
|
||||
If the local provider does not support flushing write cache (it returns
|
||||
.Er EOPNOTSUPP
|
||||
on the
|
||||
.Cm BIO_FLUSH
|
||||
request),
|
||||
.Nm hastd
|
||||
will disable
|
||||
.Ic metaflush
|
||||
automatically.
|
||||
The default value is
|
||||
.Va on .
|
||||
.Pp
|
||||
.It Ic name Aq name
|
||||
.Pp
|
||||
GEOM provider name that will appear as
|
||||
|
@ -167,6 +167,10 @@ struct hast_resource {
|
||||
off_t hr_local_mediasize;
|
||||
/* Sector size of local provider. */
|
||||
unsigned int hr_local_sectorsize;
|
||||
/* Is flushing write cache supported by the local provider? */
|
||||
bool hr_localflush;
|
||||
/* Flush write cache on metadata updates? */
|
||||
int hr_metaflush;
|
||||
|
||||
/* Descriptor for /dev/ggctl communication. */
|
||||
int hr_ggatefd;
|
||||
|
@ -386,6 +386,12 @@ resource_needs_restart(const struct hast_resource *res0,
|
||||
return (true);
|
||||
if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
|
||||
return (true);
|
||||
/*
|
||||
* When metaflush has changed we don't really need restart,
|
||||
* but it is just easier this way.
|
||||
*/
|
||||
if (res0->hr_metaflush != res1->hr_metaflush)
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
@ -416,6 +422,8 @@ resource_needs_reload(const struct hast_resource *res0,
|
||||
return (true);
|
||||
if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
|
||||
return (true);
|
||||
if (res0->hr_metaflush != res1->hr_metaflush)
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
@ -436,6 +444,7 @@ resource_reload(const struct hast_resource *res)
|
||||
nv_add_int32(nvout, (int32_t)res->hr_compression, "compression");
|
||||
nv_add_int32(nvout, (int32_t)res->hr_timeout, "timeout");
|
||||
nv_add_string(nvout, res->hr_exec, "exec");
|
||||
nv_add_int32(nvout, (int32_t)res->hr_metaflush, "metaflush");
|
||||
if (nv_error(nvout) != 0) {
|
||||
nv_free(nvout);
|
||||
pjdlog_error("Unable to allocate header for reload message.");
|
||||
@ -591,12 +600,13 @@ hastd_reload(void)
|
||||
* recreating it.
|
||||
*
|
||||
* We do just reload (send SIGHUP to worker process) if we act as
|
||||
* PRIMARY, but only if remote address, replication mode, timeout or
|
||||
* execution path has changed. For those, there is no need to restart
|
||||
* worker process.
|
||||
* PRIMARY, but only if remote address, source address, replication
|
||||
* mode, timeout, execution path or metaflush has changed.
|
||||
* For those, there is no need to restart worker process.
|
||||
* If PRIMARY receives SIGHUP, it will reconnect if remote address or
|
||||
* replication mode has changed or simply set new timeout if only
|
||||
* timeout has changed.
|
||||
* source address has changed or it will set new timeout if only timeout
|
||||
* has changed or it will update metaflush if only metaflush has
|
||||
* changed.
|
||||
*/
|
||||
TAILQ_FOREACH_SAFE(nres, &newcfg->hc_resources, hr_next, tres) {
|
||||
TAILQ_FOREACH(cres, &cfg->hc_resources, hr_next) {
|
||||
@ -627,6 +637,7 @@ hastd_reload(void)
|
||||
cres->hr_timeout = nres->hr_timeout;
|
||||
strlcpy(cres->hr_exec, nres->hr_exec,
|
||||
sizeof(cres->hr_exec));
|
||||
cres->hr_metaflush = nres->hr_metaflush;
|
||||
if (cres->hr_workerpid != 0)
|
||||
resource_reload(cres);
|
||||
}
|
||||
|
@ -68,9 +68,11 @@ static int depth0_checksum;
|
||||
static int depth0_compression;
|
||||
static int depth0_timeout;
|
||||
static char depth0_exec[PATH_MAX];
|
||||
static int depth0_metaflush;
|
||||
|
||||
static char depth1_provname[PATH_MAX];
|
||||
static char depth1_localpath[PATH_MAX];
|
||||
static int depth1_metaflush;
|
||||
|
||||
extern void yyrestart(FILE *);
|
||||
|
||||
@ -197,6 +199,7 @@ yy_config_parse(const char *config, bool exitonerror)
|
||||
strlcpy(depth0_listen_tcp6, HASTD_LISTEN_TCP6,
|
||||
sizeof(depth0_listen_tcp6));
|
||||
depth0_exec[0] = '\0';
|
||||
depth0_metaflush = 1;
|
||||
|
||||
lconfig = calloc(1, sizeof(*lconfig));
|
||||
if (lconfig == NULL) {
|
||||
@ -328,6 +331,13 @@ yy_config_parse(const char *config, bool exitonerror)
|
||||
strlcpy(curres->hr_exec, depth0_exec,
|
||||
sizeof(curres->hr_exec));
|
||||
}
|
||||
if (curres->hr_metaflush == -1) {
|
||||
/*
|
||||
* Metaflush is not set at resource-level.
|
||||
* Use global or default setting.
|
||||
*/
|
||||
curres->hr_metaflush = depth0_metaflush;
|
||||
}
|
||||
}
|
||||
|
||||
return (lconfig);
|
||||
@ -355,8 +365,8 @@ yy_config_free(struct hastd_config *config)
|
||||
}
|
||||
%}
|
||||
|
||||
%token CONTROL LISTEN PORT REPLICATION CHECKSUM COMPRESSION
|
||||
%token TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE SOURCE ON
|
||||
%token CONTROL LISTEN PORT REPLICATION CHECKSUM COMPRESSION METAFLUSH
|
||||
%token TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE SOURCE ON OFF
|
||||
%token FULLSYNC MEMSYNC ASYNC NONE CRC32 SHA256 HOLE LZF
|
||||
%token NUM STR OB CB
|
||||
|
||||
@ -364,6 +374,7 @@ yy_config_free(struct hastd_config *config)
|
||||
%type <num> replication_type
|
||||
%type <num> checksum_type
|
||||
%type <num> compression_type
|
||||
%type <num> boolean
|
||||
|
||||
%union
|
||||
{
|
||||
@ -396,6 +407,8 @@ statement:
|
||||
|
|
||||
exec_statement
|
||||
|
|
||||
metaflush_statement
|
||||
|
|
||||
node_statement
|
||||
|
|
||||
resource_statement
|
||||
@ -585,6 +598,34 @@ exec_statement: EXEC STR
|
||||
}
|
||||
;
|
||||
|
||||
metaflush_statement: METAFLUSH boolean
|
||||
{
|
||||
switch (depth) {
|
||||
case 0:
|
||||
depth0_metaflush = $2;
|
||||
break;
|
||||
case 1:
|
||||
PJDLOG_ASSERT(curres != NULL);
|
||||
depth1_metaflush = $2;
|
||||
break;
|
||||
case 2:
|
||||
if (!mynode)
|
||||
break;
|
||||
PJDLOG_ASSERT(curres != NULL);
|
||||
curres->hr_metaflush = $2;
|
||||
break;
|
||||
default:
|
||||
PJDLOG_ABORT("metaflush at wrong depth level");
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
boolean:
|
||||
ON { $$ = 1; }
|
||||
|
|
||||
OFF { $$ = 0; }
|
||||
;
|
||||
|
||||
node_statement: ON node_start OB node_entries CB
|
||||
{
|
||||
mynode = false;
|
||||
@ -660,6 +701,13 @@ resource_statement: RESOURCE resource_start OB resource_entries CB
|
||||
strlcpy(curres->hr_localpath, depth1_localpath,
|
||||
sizeof(curres->hr_localpath));
|
||||
}
|
||||
if (curres->hr_metaflush == -1 && depth1_metaflush != -1) {
|
||||
/*
|
||||
* Metaflush is not set at node-level,
|
||||
* but is set at resource-level, use it.
|
||||
*/
|
||||
curres->hr_metaflush = depth1_metaflush;
|
||||
}
|
||||
|
||||
/*
|
||||
* If provider name is not given, use resource name
|
||||
@ -713,6 +761,7 @@ resource_start: STR
|
||||
*/
|
||||
depth1_provname[0] = '\0';
|
||||
depth1_localpath[0] = '\0';
|
||||
depth1_metaflush = -1;
|
||||
hadmynode = false;
|
||||
|
||||
curres = calloc(1, sizeof(*curres));
|
||||
@ -739,6 +788,8 @@ resource_start: STR
|
||||
curres->hr_provname[0] = '\0';
|
||||
curres->hr_localpath[0] = '\0';
|
||||
curres->hr_localfd = -1;
|
||||
curres->hr_localflush = true;
|
||||
curres->hr_metaflush = -1;
|
||||
curres->hr_remoteaddr[0] = '\0';
|
||||
curres->hr_sourceaddr[0] = '\0';
|
||||
curres->hr_ggateunit = -1;
|
||||
@ -761,6 +812,8 @@ resource_entry:
|
||||
|
|
||||
exec_statement
|
||||
|
|
||||
metaflush_statement
|
||||
|
|
||||
name_statement
|
||||
|
|
||||
local_statement
|
||||
@ -869,6 +922,8 @@ resource_node_entry:
|
||||
remote_statement
|
||||
|
|
||||
source_statement
|
||||
|
|
||||
metaflush_statement
|
||||
;
|
||||
|
||||
remote_statement: REMOTE remote_str
|
||||
|
@ -296,6 +296,17 @@ hast_activemap_flush(struct hast_resource *res)
|
||||
pjdlog_errno(LOG_ERR, "Unable to flush activemap to disk");
|
||||
return (-1);
|
||||
}
|
||||
if (res->hr_metaflush == 1 && g_flush(res->hr_localfd) == -1) {
|
||||
if (errno == EOPNOTSUPP) {
|
||||
pjdlog_warning("The %s provider doesn't support flushing write cache. Disabling it.",
|
||||
res->hr_localpath);
|
||||
res->hr_metaflush = 0;
|
||||
} else {
|
||||
pjdlog_errno(LOG_ERR,
|
||||
"Unable to flush disk cache on activemap update");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1202,7 +1213,7 @@ ggate_recv_thread(void *arg)
|
||||
break;
|
||||
}
|
||||
pjdlog_debug(2,
|
||||
"ggate_recv: (%p) Moving request to the send queues.",
|
||||
"ggate_recv: (%p) Moving request to the send queue.",
|
||||
hio);
|
||||
refcount_init(&hio->hio_countdown, ncomps);
|
||||
for (ii = 0; ii < ncomps; ii++)
|
||||
@ -1293,8 +1304,15 @@ local_send_thread(void *arg)
|
||||
}
|
||||
break;
|
||||
case BIO_FLUSH:
|
||||
if (!res->hr_localflush) {
|
||||
ret = -1;
|
||||
errno = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
ret = g_flush(res->hr_localfd);
|
||||
if (ret < 0) {
|
||||
if (errno == EOPNOTSUPP)
|
||||
res->hr_localflush = false;
|
||||
hio->hio_errors[ncomp] = errno;
|
||||
reqlog(LOG_WARNING, 0, ggio,
|
||||
"Local request failed (%s): ",
|
||||
@ -1999,6 +2017,7 @@ primary_config_reload(struct hast_resource *res, struct nv *nv)
|
||||
nv_assert(nv, "compression");
|
||||
nv_assert(nv, "timeout");
|
||||
nv_assert(nv, "exec");
|
||||
nv_assert(nv, "metaflush");
|
||||
|
||||
ncomps = HAST_NCOMPONENTS;
|
||||
|
||||
@ -2009,6 +2028,7 @@ primary_config_reload(struct hast_resource *res, struct nv *nv)
|
||||
#define MODIFIED_COMPRESSION 0x10
|
||||
#define MODIFIED_TIMEOUT 0x20
|
||||
#define MODIFIED_EXEC 0x40
|
||||
#define MODIFIED_METAFLUSH 0x80
|
||||
modified = 0;
|
||||
|
||||
vstr = nv_get_string(nv, "remoteaddr");
|
||||
@ -2050,6 +2070,11 @@ primary_config_reload(struct hast_resource *res, struct nv *nv)
|
||||
strlcpy(gres->hr_exec, vstr, sizeof(gres->hr_exec));
|
||||
modified |= MODIFIED_EXEC;
|
||||
}
|
||||
vint = nv_get_int32(nv, "metaflush");
|
||||
if (gres->hr_metaflush != vint) {
|
||||
gres->hr_metaflush = vint;
|
||||
modified |= MODIFIED_METAFLUSH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change timeout for connected sockets.
|
||||
@ -2099,6 +2124,7 @@ primary_config_reload(struct hast_resource *res, struct nv *nv)
|
||||
#undef MODIFIED_COMPRESSION
|
||||
#undef MODIFIED_TIMEOUT
|
||||
#undef MODIFIED_EXEC
|
||||
#undef MODIFIED_METAFLUSH
|
||||
|
||||
pjdlog_info("Configuration reloaded successfully.");
|
||||
}
|
||||
|
@ -664,7 +664,7 @@ disk_thread(void *arg)
|
||||
struct hast_resource *res = arg;
|
||||
struct hio *hio;
|
||||
ssize_t ret;
|
||||
bool clear_activemap;
|
||||
bool clear_activemap, logerror;
|
||||
|
||||
clear_activemap = true;
|
||||
|
||||
@ -699,8 +699,10 @@ disk_thread(void *arg)
|
||||
free(map);
|
||||
clear_activemap = false;
|
||||
pjdlog_debug(1, "Local activemap cleared.");
|
||||
break;
|
||||
}
|
||||
reqlog(LOG_DEBUG, 2, -1, hio, "disk: (%p) Got request: ", hio);
|
||||
logerror = true;
|
||||
/* Handle the actual request. */
|
||||
switch (hio->hio_cmd) {
|
||||
case HIO_READ:
|
||||
@ -735,14 +737,23 @@ disk_thread(void *arg)
|
||||
hio->hio_error = 0;
|
||||
break;
|
||||
case HIO_FLUSH:
|
||||
if (!res->hr_localflush) {
|
||||
ret = -1;
|
||||
hio->hio_error = EOPNOTSUPP;
|
||||
logerror = false;
|
||||
break;
|
||||
}
|
||||
ret = g_flush(res->hr_localfd);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
if (errno == EOPNOTSUPP)
|
||||
res->hr_localflush = false;
|
||||
hio->hio_error = errno;
|
||||
else
|
||||
} else {
|
||||
hio->hio_error = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (hio->hio_error != 0) {
|
||||
if (logerror && hio->hio_error != 0) {
|
||||
reqlog(LOG_ERR, 0, hio->hio_error, hio,
|
||||
"Request failed: ");
|
||||
}
|
||||
|
@ -53,12 +53,14 @@ checksum { DP; return CHECKSUM; }
|
||||
compression { DP; return COMPRESSION; }
|
||||
timeout { DP; return TIMEOUT; }
|
||||
exec { DP; return EXEC; }
|
||||
metaflush { DP; return METAFLUSH; }
|
||||
resource { DP; return RESOURCE; }
|
||||
name { DP; return NAME; }
|
||||
local { DP; return LOCAL; }
|
||||
remote { DP; return REMOTE; }
|
||||
source { DP; return SOURCE; }
|
||||
on { DP; return ON; }
|
||||
off { DP; return OFF; }
|
||||
fullsync { DP; return FULLSYNC; }
|
||||
memsync { DP; return MEMSYNC; }
|
||||
async { DP; return ASYNC; }
|
||||
|
@ -238,7 +238,7 @@ This command takes a long time.
|
||||
Get updated sources as configured in
|
||||
.Xr make.conf 5 .
|
||||
.It Cm targets
|
||||
Print a list of supported
|
||||
Print a list of supported
|
||||
.Va TARGET
|
||||
/
|
||||
.Va TARGET_ARCH
|
||||
@ -399,21 +399,31 @@ It defaults to
|
||||
.It Va KERNFAST
|
||||
If set, the build target
|
||||
.Cm buildkernel
|
||||
defaults to setting
|
||||
defaults to setting
|
||||
.Va NO_KERNELCLEAN ,
|
||||
.Va NO_KERNELCONFIG ,
|
||||
.Va NO_KERNELDEPEND
|
||||
.Va NO_KERNELDEPEND
|
||||
and
|
||||
.Va NO_KERNELOBJ .
|
||||
When set to a value other than
|
||||
.Cm 1
|
||||
then
|
||||
.Va KERNCONF
|
||||
is set to the value of
|
||||
then
|
||||
.Va KERNCONF
|
||||
is set to the value of
|
||||
.Va KERNFAST .
|
||||
.It Va LOCAL_DIRS
|
||||
If set, this variable supplies a list of additional directories to
|
||||
build, relative to the root of the source tree.
|
||||
.It Va PORTS_MODULES
|
||||
A list of ports with kernel modules that should be built and installed
|
||||
as part of the
|
||||
.Cm buildkernel
|
||||
and
|
||||
.Cm installkernel
|
||||
process.
|
||||
.Bd -literal -offset indent
|
||||
make PORTS_MODULES=emulators/kqemu-kmod kernel
|
||||
.Ed
|
||||
.It Va SUBDIR_OVERRIDE
|
||||
Override the default list of sub-directories and only build the
|
||||
sub-directory named in this variable.
|
||||
@ -442,11 +452,11 @@ output.
|
||||
Set this to cross-build for a different architecture.
|
||||
If not set,
|
||||
.Va TARGET_ARCH
|
||||
defaults to the current machine architecture, unless
|
||||
defaults to the current machine architecture, unless
|
||||
.Va TARGET
|
||||
is also set, in which case it defaults to the appropriate
|
||||
value for that platform.
|
||||
Typically, one only needs to set
|
||||
Typically, one only needs to set
|
||||
.Va TARGET .
|
||||
.El
|
||||
.Pp
|
||||
|
@ -78,6 +78,7 @@ delphij [label="Xin Li\ndelphij@FreeBSD.org\n2006/05/01"]
|
||||
demon [label="Dmitry Sivachenko\ndemon@FreeBSD.org\n2000/11/13"]
|
||||
dhn [label="Dennis Herrmann\ndhn@FreeBSD.org\n2009/03/03"]
|
||||
dryice [label="Dryice Dong Liu\ndryice@FreeBSD.org\n2006/12/25"]
|
||||
eadler [label="Eitan Adler\neadler@FreeBSD.org\n2011/08/17"]
|
||||
edwin [label="Edwin Groothuis\nedwin@FreeBSD.org\n2002/10/22"]
|
||||
ehaupt [label="Emanuel Haupt\nehaupt@FreeBSD.org\n2005/10/03"]
|
||||
eik [label="Oliver Eikemeier\neik@FreeBSD.org\n2003/11/12"]
|
||||
@ -209,6 +210,7 @@ arved -> stefan
|
||||
|
||||
asami -> obrien
|
||||
|
||||
bapt -> eadler
|
||||
bapt -> jlaffaye
|
||||
|
||||
beat -> decke
|
||||
@ -385,6 +387,7 @@ rafan -> chinsan
|
||||
rene -> crees
|
||||
|
||||
sahil -> culot
|
||||
sahil -> eadler
|
||||
|
||||
sat -> beech
|
||||
|
||||
|
@ -1488,7 +1488,7 @@ mfi_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
struct mfi_command *cm;
|
||||
union mfi_sgl *sgl;
|
||||
struct mfi_softc *sc;
|
||||
int i, dir;
|
||||
int i, j, first, dir;
|
||||
|
||||
cm = (struct mfi_command *)arg;
|
||||
sc = cm->cm_sc;
|
||||
@ -1502,19 +1502,33 @@ mfi_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
return;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
if (cm->cm_frame->header.cmd == MFI_CMD_STP) {
|
||||
first = cm->cm_stp_len;
|
||||
if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
|
||||
sgl->sg32[j].addr = segs[0].ds_addr;
|
||||
sgl->sg32[j++].len = first;
|
||||
} else {
|
||||
sgl->sg64[j].addr = segs[0].ds_addr;
|
||||
sgl->sg64[j++].len = first;
|
||||
}
|
||||
} else
|
||||
first = 0;
|
||||
if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
sgl->sg32[i].addr = segs[i].ds_addr;
|
||||
sgl->sg32[i].len = segs[i].ds_len;
|
||||
sgl->sg32[j].addr = segs[i].ds_addr + first;
|
||||
sgl->sg32[j++].len = segs[i].ds_len - first;
|
||||
first = 0;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
sgl->sg64[i].addr = segs[i].ds_addr;
|
||||
sgl->sg64[i].len = segs[i].ds_len;
|
||||
sgl->sg64[j].addr = segs[i].ds_addr + first;
|
||||
sgl->sg64[j++].len = segs[i].ds_len - first;
|
||||
first = 0;
|
||||
}
|
||||
hdr->flags |= MFI_FRAME_SGL64;
|
||||
}
|
||||
hdr->sg_count = nsegs;
|
||||
hdr->sg_count = j;
|
||||
|
||||
dir = 0;
|
||||
if (cm->cm_flags & MFI_CMD_DATAIN) {
|
||||
@ -1525,6 +1539,8 @@ mfi_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
dir |= BUS_DMASYNC_PREWRITE;
|
||||
hdr->flags |= MFI_FRAME_DIR_WRITE;
|
||||
}
|
||||
if (cm->cm_frame->header.cmd == MFI_CMD_STP)
|
||||
dir |= BUS_DMASYNC_PREWRITE;
|
||||
bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
|
||||
cm->cm_flags |= MFI_CMD_MAPPED;
|
||||
|
||||
@ -1602,7 +1618,8 @@ mfi_complete(struct mfi_softc *sc, struct mfi_command *cm)
|
||||
|
||||
if ((cm->cm_flags & MFI_CMD_MAPPED) != 0) {
|
||||
dir = 0;
|
||||
if (cm->cm_flags & MFI_CMD_DATAIN)
|
||||
if ((cm->cm_flags & MFI_CMD_DATAIN) ||
|
||||
(cm->cm_frame->header.cmd == MFI_CMD_STP))
|
||||
dir |= BUS_DMASYNC_POSTREAD;
|
||||
if (cm->cm_flags & MFI_CMD_DATAOUT)
|
||||
dir |= BUS_DMASYNC_POSTWRITE;
|
||||
@ -1927,7 +1944,8 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
struct mfi_command *cm = NULL;
|
||||
uint32_t context;
|
||||
union mfi_sense_ptr sense_ptr;
|
||||
uint8_t *data = NULL, *temp;
|
||||
uint8_t *data = NULL, *temp, *addr;
|
||||
size_t len;
|
||||
int i;
|
||||
struct mfi_ioc_passthru *iop = (struct mfi_ioc_passthru *)arg;
|
||||
#ifdef __amd64__
|
||||
@ -2024,6 +2042,21 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
if (cm->cm_flags == 0)
|
||||
cm->cm_flags |= MFI_CMD_DATAIN | MFI_CMD_DATAOUT;
|
||||
cm->cm_len = cm->cm_frame->header.data_len;
|
||||
if (cm->cm_frame->header.cmd == MFI_CMD_STP) {
|
||||
#ifdef __amd64__
|
||||
if (cmd == MFI_CMD) {
|
||||
#endif
|
||||
/* Native */
|
||||
cm->cm_stp_len = ioc->mfi_sgl[0].iov_len;
|
||||
#ifdef __amd64__
|
||||
} else {
|
||||
/* 32bit on 64bit */
|
||||
ioc32 = (struct mfi_ioc_packet32 *)ioc;
|
||||
cm->cm_stp_len = ioc32->mfi_sgl[0].iov_len;
|
||||
}
|
||||
#endif
|
||||
cm->cm_len += cm->cm_stp_len;
|
||||
}
|
||||
if (cm->cm_len &&
|
||||
(cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) {
|
||||
cm->cm_data = data = malloc(cm->cm_len, M_MFIBUF,
|
||||
@ -2040,35 +2073,30 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
cm->cm_frame->header.context = context;
|
||||
|
||||
temp = data;
|
||||
if (cm->cm_flags & MFI_CMD_DATAOUT) {
|
||||
if ((cm->cm_flags & MFI_CMD_DATAOUT) ||
|
||||
(cm->cm_frame->header.cmd == MFI_CMD_STP)) {
|
||||
for (i = 0; i < ioc->mfi_sge_count; i++) {
|
||||
#ifdef __amd64__
|
||||
if (cmd == MFI_CMD) {
|
||||
/* Native */
|
||||
error = copyin(ioc->mfi_sgl[i].iov_base,
|
||||
temp,
|
||||
ioc->mfi_sgl[i].iov_len);
|
||||
} else {
|
||||
void *temp_convert;
|
||||
/* 32bit */
|
||||
ioc32 = (struct mfi_ioc_packet32 *)ioc;
|
||||
temp_convert =
|
||||
PTRIN(ioc32->mfi_sgl[i].iov_base);
|
||||
error = copyin(temp_convert,
|
||||
temp,
|
||||
ioc32->mfi_sgl[i].iov_len);
|
||||
}
|
||||
#else
|
||||
error = copyin(ioc->mfi_sgl[i].iov_base,
|
||||
temp,
|
||||
ioc->mfi_sgl[i].iov_len);
|
||||
#endif
|
||||
/* Native */
|
||||
addr = ioc->mfi_sgl[i].iov_base;
|
||||
len = ioc->mfi_sgl[i].iov_len;
|
||||
#ifdef __amd64__
|
||||
} else {
|
||||
/* 32bit on 64bit */
|
||||
ioc32 = (struct mfi_ioc_packet32 *)ioc;
|
||||
addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
|
||||
len = ioc32->mfi_sgl[i].iov_len;
|
||||
}
|
||||
#endif
|
||||
error = copyin(addr, temp, len);
|
||||
if (error != 0) {
|
||||
device_printf(sc->mfi_dev,
|
||||
"Copy in failed\n");
|
||||
goto out;
|
||||
}
|
||||
temp = &temp[ioc->mfi_sgl[i].iov_len];
|
||||
temp = &temp[len];
|
||||
}
|
||||
}
|
||||
|
||||
@ -2098,35 +2126,30 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td
|
||||
mtx_unlock(&sc->mfi_io_lock);
|
||||
|
||||
temp = data;
|
||||
if (cm->cm_flags & MFI_CMD_DATAIN) {
|
||||
if ((cm->cm_flags & MFI_CMD_DATAIN) ||
|
||||
(cm->cm_frame->header.cmd == MFI_CMD_STP)) {
|
||||
for (i = 0; i < ioc->mfi_sge_count; i++) {
|
||||
#ifdef __amd64__
|
||||
if (cmd == MFI_CMD) {
|
||||
/* Native */
|
||||
error = copyout(temp,
|
||||
ioc->mfi_sgl[i].iov_base,
|
||||
ioc->mfi_sgl[i].iov_len);
|
||||
} else {
|
||||
void *temp_convert;
|
||||
/* 32bit */
|
||||
ioc32 = (struct mfi_ioc_packet32 *)ioc;
|
||||
temp_convert =
|
||||
PTRIN(ioc32->mfi_sgl[i].iov_base);
|
||||
error = copyout(temp,
|
||||
temp_convert,
|
||||
ioc32->mfi_sgl[i].iov_len);
|
||||
}
|
||||
#else
|
||||
error = copyout(temp,
|
||||
ioc->mfi_sgl[i].iov_base,
|
||||
ioc->mfi_sgl[i].iov_len);
|
||||
#endif
|
||||
/* Native */
|
||||
addr = ioc->mfi_sgl[i].iov_base;
|
||||
len = ioc->mfi_sgl[i].iov_len;
|
||||
#ifdef __amd64__
|
||||
} else {
|
||||
/* 32bit on 64bit */
|
||||
ioc32 = (struct mfi_ioc_packet32 *)ioc;
|
||||
addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
|
||||
len = ioc32->mfi_sgl[i].iov_len;
|
||||
}
|
||||
#endif
|
||||
error = copyout(temp, addr, len);
|
||||
if (error != 0) {
|
||||
device_printf(sc->mfi_dev,
|
||||
"Copy out failed\n");
|
||||
goto out;
|
||||
}
|
||||
temp = &temp[ioc->mfi_sgl[i].iov_len];
|
||||
temp = &temp[len];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,7 @@ struct mfi_command {
|
||||
union mfi_sgl *cm_sg;
|
||||
void *cm_data;
|
||||
int cm_len;
|
||||
int cm_stp_len;
|
||||
int cm_total_frame_size;
|
||||
int cm_extra_frames;
|
||||
int cm_flags;
|
||||
|
@ -566,8 +566,10 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr,
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
if (id != 0)
|
||||
copyin(ugd->ugd_data, &id, 1);
|
||||
error = uhid_get_report(sc, ugd->ugd_report_type, id,
|
||||
NULL, ugd->ugd_data, size);
|
||||
NULL, ugd->ugd_data, imin(ugd->ugd_maxlen, size));
|
||||
break;
|
||||
|
||||
case USB_SET_REPORT:
|
||||
@ -592,8 +594,10 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr,
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
if (id != 0)
|
||||
copyin(ugd->ugd_data, &id, 1);
|
||||
error = uhid_set_report(sc, ugd->ugd_report_type, id,
|
||||
NULL, ugd->ugd_data, size);
|
||||
NULL, ugd->ugd_data, imin(ugd->ugd_maxlen, size));
|
||||
break;
|
||||
|
||||
case USB_GET_REPORT_ID:
|
||||
|
@ -70,9 +70,14 @@ pr_init_t raw_init;
|
||||
* Library routines for raw socket usrreq functions; will always be wrapped
|
||||
* so that protocol-specific functions can be handled.
|
||||
*/
|
||||
typedef int (*raw_input_cb_fn)(struct mbuf *, struct sockproto *,
|
||||
struct sockaddr *, struct rawcb *);
|
||||
|
||||
int raw_attach(struct socket *, int);
|
||||
void raw_detach(struct rawcb *);
|
||||
void raw_input(struct mbuf *, struct sockproto *, struct sockaddr *);
|
||||
void raw_input_ext(struct mbuf *, struct sockproto *, struct sockaddr *,
|
||||
raw_input_cb_fn);
|
||||
|
||||
/*
|
||||
* Generic pr_usrreqs entries for raw socket protocols, usually wrapped so
|
||||
|
@ -70,6 +70,14 @@ raw_init(void)
|
||||
*/
|
||||
void
|
||||
raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src)
|
||||
{
|
||||
|
||||
return (raw_input_ext(m0, proto, src, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
raw_input_ext(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src,
|
||||
raw_input_cb_fn cb)
|
||||
{
|
||||
struct rawcb *rp;
|
||||
struct mbuf *m = m0;
|
||||
@ -83,6 +91,8 @@ raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src)
|
||||
if (rp->rcb_proto.sp_protocol &&
|
||||
rp->rcb_proto.sp_protocol != proto->sp_protocol)
|
||||
continue;
|
||||
if (cb != NULL && (*cb)(m, proto, src, rp) != 0)
|
||||
continue;
|
||||
if (last) {
|
||||
struct mbuf *n;
|
||||
n = m_copy(m, 0, (int)M_COPYALL);
|
||||
|
@ -384,7 +384,7 @@ miss:
|
||||
*/
|
||||
bzero(&info, sizeof(info));
|
||||
info.rti_info[RTAX_DST] = dst;
|
||||
rt_missmsg(msgtype, &info, 0, err);
|
||||
rt_missmsg_fib(msgtype, &info, 0, err, fibnum);
|
||||
}
|
||||
done:
|
||||
if (newrt)
|
||||
@ -609,7 +609,7 @@ out:
|
||||
info.rti_info[RTAX_GATEWAY] = gateway;
|
||||
info.rti_info[RTAX_NETMASK] = netmask;
|
||||
info.rti_info[RTAX_AUTHOR] = src;
|
||||
rt_missmsg(RTM_REDIRECT, &info, flags, error);
|
||||
rt_missmsg_fib(RTM_REDIRECT, &info, flags, error, fibnum);
|
||||
if (ifa != NULL)
|
||||
ifa_free(ifa);
|
||||
}
|
||||
@ -1522,7 +1522,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
|
||||
}
|
||||
RT_ADDREF(rt);
|
||||
RT_UNLOCK(rt);
|
||||
rt_newaddrmsg(cmd, ifa, error, rt);
|
||||
rt_newaddrmsg_fib(cmd, ifa, error, rt, fibnum);
|
||||
RT_LOCK(rt);
|
||||
RT_REMREF(rt);
|
||||
if (cmd == RTM_DELETE) {
|
||||
|
@ -369,7 +369,9 @@ void rt_ieee80211msg(struct ifnet *, int, void *, size_t);
|
||||
void rt_ifannouncemsg(struct ifnet *, int);
|
||||
void rt_ifmsg(struct ifnet *);
|
||||
void rt_missmsg(int, struct rt_addrinfo *, int, int);
|
||||
void rt_missmsg_fib(int, struct rt_addrinfo *, int, int, int);
|
||||
void rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
|
||||
void rt_newaddrmsg_fib(int, struct ifaddr *, int, struct rtentry *, int);
|
||||
void rt_newmaddrmsg(int, struct ifmultiaddr *);
|
||||
int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
|
||||
void rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);
|
||||
|
@ -122,6 +122,13 @@ MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
|
||||
static struct sockaddr route_src = { 2, PF_ROUTE, };
|
||||
static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, };
|
||||
|
||||
/*
|
||||
* Used by rtsock/raw_input callback code to decide whether to filter the update
|
||||
* notification to a socket bound to a particular FIB.
|
||||
*/
|
||||
#define RTS_FILTER_FIB M_PROTO8
|
||||
#define RTS_ALLFIBS -1
|
||||
|
||||
static struct {
|
||||
int ip_count; /* attached w/ AF_INET */
|
||||
int ip6_count; /* attached w/ AF_INET6 */
|
||||
@ -196,6 +203,31 @@ rts_init(void)
|
||||
}
|
||||
SYSINIT(rtsock, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rts_init, 0);
|
||||
|
||||
static int
|
||||
raw_input_rts_cb(struct mbuf *m, struct sockproto *proto, struct sockaddr *src,
|
||||
struct rawcb *rp)
|
||||
{
|
||||
int fibnum;
|
||||
|
||||
KASSERT(m != NULL, ("%s: m is NULL", __func__));
|
||||
KASSERT(proto != NULL, ("%s: proto is NULL", __func__));
|
||||
KASSERT(rp != NULL, ("%s: rp is NULL", __func__));
|
||||
|
||||
/* No filtering requested. */
|
||||
if ((m->m_flags & RTS_FILTER_FIB) == 0)
|
||||
return (0);
|
||||
|
||||
/* Check if it is a rts and the fib matches the one of the socket. */
|
||||
fibnum = M_GETFIB(m);
|
||||
if (proto->sp_family != PF_ROUTE ||
|
||||
rp->rcb_socket == NULL ||
|
||||
rp->rcb_socket->so_fibnum == fibnum)
|
||||
return (0);
|
||||
|
||||
/* Filtering requested and no match, the socket shall be skipped. */
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
rts_input(struct mbuf *m)
|
||||
{
|
||||
@ -212,7 +244,7 @@ rts_input(struct mbuf *m)
|
||||
} else
|
||||
route_proto.sp_protocol = 0;
|
||||
|
||||
raw_input(m, &route_proto, &route_src);
|
||||
raw_input_ext(m, &route_proto, &route_src, raw_input_rts_cb);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -885,6 +917,8 @@ flush:
|
||||
m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
|
||||
}
|
||||
if (m) {
|
||||
M_SETFIB(m, so->so_fibnum);
|
||||
m->m_flags |= RTS_FILTER_FIB;
|
||||
if (rp) {
|
||||
/*
|
||||
* XXX insure we don't get a copy by
|
||||
@ -1127,7 +1161,8 @@ again:
|
||||
* destination.
|
||||
*/
|
||||
void
|
||||
rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
|
||||
rt_missmsg_fib(int type, struct rt_addrinfo *rtinfo, int flags, int error,
|
||||
int fibnum)
|
||||
{
|
||||
struct rt_msghdr *rtm;
|
||||
struct mbuf *m;
|
||||
@ -1138,6 +1173,14 @@ rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
|
||||
m = rt_msg1(type, rtinfo);
|
||||
if (m == NULL)
|
||||
return;
|
||||
|
||||
if (fibnum != RTS_ALLFIBS) {
|
||||
KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: fibnum out "
|
||||
"of range 0 <= %d < %d", __func__, fibnum, rt_numfibs));
|
||||
M_SETFIB(m, fibnum);
|
||||
m->m_flags |= RTS_FILTER_FIB;
|
||||
}
|
||||
|
||||
rtm = mtod(m, struct rt_msghdr *);
|
||||
rtm->rtm_flags = RTF_DONE | flags;
|
||||
rtm->rtm_errno = error;
|
||||
@ -1145,6 +1188,13 @@ rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
|
||||
rt_dispatch(m, sa);
|
||||
}
|
||||
|
||||
void
|
||||
rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
|
||||
{
|
||||
|
||||
rt_missmsg_fib(type, rtinfo, flags, error, RTS_ALLFIBS);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called to generate a message from the routing
|
||||
* socket indicating that the status of a network interface has changed.
|
||||
@ -1179,7 +1229,8 @@ rt_ifmsg(struct ifnet *ifp)
|
||||
* copies of it.
|
||||
*/
|
||||
void
|
||||
rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
|
||||
rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt,
|
||||
int fibnum)
|
||||
{
|
||||
struct rt_addrinfo info;
|
||||
struct sockaddr *sa = NULL;
|
||||
@ -1237,10 +1288,24 @@ rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
|
||||
rtm->rtm_errno = error;
|
||||
rtm->rtm_addrs = info.rti_addrs;
|
||||
}
|
||||
if (fibnum != RTS_ALLFIBS) {
|
||||
KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: "
|
||||
"fibnum out of range 0 <= %d < %d", __func__,
|
||||
fibnum, rt_numfibs));
|
||||
M_SETFIB(m, fibnum);
|
||||
m->m_flags |= RTS_FILTER_FIB;
|
||||
}
|
||||
rt_dispatch(m, sa);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
|
||||
{
|
||||
|
||||
rt_newaddrmsg_fib(cmd, ifa, error, rt, RTS_ALLFIBS);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the analogue to the rt_newaddrmsg which performs the same
|
||||
* function but for multicast group memberhips. This is easier since
|
||||
|
@ -2348,7 +2348,6 @@ vm_page_clear_dirty_mask(vm_page_t m, int pagebits)
|
||||
* If the object is locked and the page is neither VPO_BUSY nor
|
||||
* PGA_WRITEABLE, then the page's dirty field cannot possibly be
|
||||
* set by a concurrent pmap operation.
|
||||
*
|
||||
*/
|
||||
VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
|
||||
if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0)
|
||||
@ -2363,7 +2362,7 @@ vm_page_clear_dirty_mask(vm_page_t m, int pagebits)
|
||||
* For PAGE_SIZE == 32768 case, compiler already
|
||||
* properly aligns the dirty field, so no forcible
|
||||
* alignment is needed. Only require existence of
|
||||
* atomic_clear_64 when page size if 32768.
|
||||
* atomic_clear_64 when page size is 32768.
|
||||
*/
|
||||
addr = (uintptr_t)&m->dirty;
|
||||
#if PAGE_SIZE == 32768
|
||||
@ -2373,9 +2372,9 @@ vm_page_clear_dirty_mask(vm_page_t m, int pagebits)
|
||||
atomic_clear_32((uint32_t *)addr, pagebits);
|
||||
#else /* PAGE_SIZE <= 8192 */
|
||||
/*
|
||||
* Use a trick to perform an 32bit atomic on the
|
||||
* contained aligned word, to not depend on existence
|
||||
* of the atomic_clear_{8, 16}.
|
||||
* Use a trick to perform a 32-bit atomic on the
|
||||
* containing aligned word, to not depend on the existence
|
||||
* of atomic_clear_{8, 16}.
|
||||
*/
|
||||
shift = addr & (sizeof(uint32_t) - 1);
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
|
@ -105,7 +105,7 @@
|
||||
* the field without holding that lock. If the underlying
|
||||
* architecture does not support atomic read-modify-write
|
||||
* operations on the field's type, then the machine-independent
|
||||
* layer uses 32bit atomic on the aligned 32bit word that
|
||||
* layer uses a 32-bit atomic on the aligned 32-bit word that
|
||||
* contains the dirty field. In the machine-independent layer,
|
||||
* the implementation of read-modify-write operations on the
|
||||
* field is encapsulated in vm_page_clear_dirty_mask().
|
||||
|
@ -47,6 +47,7 @@
|
||||
02/02 Michael W Lucas <mwlucas@FreeBSD.org> born in Detroit, Michigan, United States, 1967
|
||||
02/02 Dmitry Chagin <dchagin@FreeBSD.org> born in Stalingrad, USSR, 1976
|
||||
02/02 Yoichi Nakayama <yoichi@FreeBSD.org> born in Tsu, Mie, Japan, 1976
|
||||
02/04 Eitan Adler <eadler@FreeBSD.org> born in West Hempstead, New York, United States, 1991
|
||||
02/05 Frank Laszlo <laszlof@FreeBSD.org> born in Howell, Michigan, United States, 1983
|
||||
02/10 David Greenman <dg@FreeBSD.org> born in Portland, Oregon, United States, 1968
|
||||
02/10 Paul Richards <paul@FreeBSD.org> born in Ammanford, Carmarthenshire, United Kingdom, 1968
|
||||
|
@ -26,11 +26,10 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/limits.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -31,7 +31,7 @@
|
||||
.\" @(#)find.1 8.7 (Berkeley) 5/9/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 17, 2010
|
||||
.Dd September 28, 2011
|
||||
.Dt FIND 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -507,7 +507,7 @@ This primary always evaluates to true.
|
||||
The following information for the current file is written to standard output:
|
||||
its inode number, size in 512-byte blocks, file permissions, number of hard
|
||||
links, owner, group, size in bytes, last modification time, and pathname.
|
||||
If the file is a block or character special file, the major and minor numbers
|
||||
If the file is a block or character special file, the device number
|
||||
will be displayed instead of the size in bytes.
|
||||
If the file is a symbolic link, the pathname of the linked-to file will be
|
||||
displayed preceded by
|
||||
|
@ -70,8 +70,7 @@ printlong(char *name, char *accpath, struct stat *sb)
|
||||
group_from_gid(sb->st_gid, 0));
|
||||
|
||||
if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode))
|
||||
(void)printf("%3d, %3d ", major(sb->st_rdev),
|
||||
minor(sb->st_rdev));
|
||||
(void)printf("%#8jx ", (uintmax_t)sb->st_rdev);
|
||||
else
|
||||
(void)printf("%8"PRId64" ", sb->st_size);
|
||||
printtime(sb->st_mtime);
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)fstat.1 8.3 (Berkeley) 2/25/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 9, 2009
|
||||
.Dd September 28, 2011
|
||||
.Dt FSTAT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -142,7 +142,7 @@ pathname that the file system the file resides in is mounted on.
|
||||
If the
|
||||
.Fl n
|
||||
flag is specified, this header is present and is the
|
||||
major/minor number of the device that this file resides in.
|
||||
number of the device that this file resides in.
|
||||
.It Li INUM
|
||||
The inode number of the file.
|
||||
.It Li MODE
|
||||
|
@ -411,7 +411,7 @@ print_pts_info(struct procstat *procstat, struct filestat *fst)
|
||||
}
|
||||
printf("* pseudo-terminal master ");
|
||||
if (nflg || !*pts.devname) {
|
||||
printf("%10d,%-2d", major(pts.dev), minor(pts.dev));
|
||||
printf("%#10jx", (uintmax_t)pts.dev);
|
||||
} else {
|
||||
printf("%10s", pts.devname);
|
||||
}
|
||||
@ -441,7 +441,7 @@ print_vnode_info(struct procstat *procstat, struct filestat *fst)
|
||||
}
|
||||
|
||||
if (nflg)
|
||||
printf(" %2d,%-2d", major(vn.vn_fsid), minor(vn.vn_fsid));
|
||||
printf(" %#8jx", (uintmax_t)vn.vn_fsid);
|
||||
else if (vn.vn_mntdir != NULL)
|
||||
(void)printf(" %-8s", vn.vn_mntdir);
|
||||
|
||||
@ -457,7 +457,7 @@ print_vnode_info(struct procstat *procstat, struct filestat *fst)
|
||||
|
||||
if (vn.vn_type == PS_FST_VTYPE_VBLK || vn.vn_type == PS_FST_VTYPE_VCHR) {
|
||||
if (nflg || !*vn.vn_devname)
|
||||
printf(" %2d,%-2d", major(vn.vn_dev), minor(vn.vn_dev));
|
||||
printf(" %#6jx", (uintmax_t)vn.vn_dev);
|
||||
else {
|
||||
printf(" %6s", vn.vn_devname);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: zuncompress.c,v 1.8 2010/11/06 21:42:32 mrg Exp $ */
|
||||
/* $NetBSD: zuncompress.c,v 1.11 2011/08/16 13:55:02 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1985, 1986, 1992, 1993
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)script.1 8.1 (Berkeley) 6/6/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 22, 2004
|
||||
.Dd September 28, 2011
|
||||
.Dt SCRIPT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -73,15 +73,16 @@ or
|
||||
.Pa typescript ,
|
||||
retaining the prior contents.
|
||||
.It Fl k
|
||||
Log keys sent to program as well as output.
|
||||
Log keys sent to the program as well as output.
|
||||
.It Fl q
|
||||
Run in quiet mode, omit the start and stop status messages.
|
||||
.It Fl t Ar time
|
||||
Specify time interval between flushing script output file.
|
||||
Specify the interval at which the script output file will be flushed
|
||||
to disk, in seconds.
|
||||
A value of 0
|
||||
causes
|
||||
.Nm
|
||||
to flush for every character I/O event.
|
||||
to flush after every character I/O event.
|
||||
The default interval is
|
||||
30 seconds.
|
||||
.El
|
||||
@ -136,13 +137,15 @@ If
|
||||
.Ev SHELL
|
||||
is not set, the Bourne shell
|
||||
is assumed.
|
||||
(Most shells set this variable automatically).
|
||||
.Pq Most shells set this variable automatically .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr csh 1
|
||||
(for the
|
||||
.Po
|
||||
for the
|
||||
.Em history
|
||||
mechanism).
|
||||
mechanism
|
||||
.Pc .
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
@ -165,13 +168,15 @@ mode, echo cancelling is far from ideal.
|
||||
The slave terminal mode is checked
|
||||
for ECHO mode to check when to avoid manual echo logging.
|
||||
This does not
|
||||
work when in a raw mode where the program being run is doing manual echo.
|
||||
work when the terminal is in a raw mode where
|
||||
the program being run is doing manual echo.
|
||||
.Pp
|
||||
If the
|
||||
If
|
||||
.Nm
|
||||
reads zero bytes from the terminal it switches to a mode when it probes read
|
||||
only once a second until it gets some data.
|
||||
This prevents the
|
||||
reads zero bytes from the terminal, it switches to a mode when it
|
||||
only attempts to read
|
||||
once a second until there is data to read.
|
||||
This prevents
|
||||
.Nm
|
||||
spinning on zero-byte reads, but might cause a 1-second delay in
|
||||
processing of the user input.
|
||||
from spinning on zero-byte reads, but might cause a 1-second delay in
|
||||
processing of user input.
|
||||
|
@ -99,8 +99,7 @@ a debounce value, and an action.
|
||||
There must be whitespace between the parts.
|
||||
.Pp
|
||||
The item names are similar to those used by
|
||||
.Xr usbhidctl 1 ,
|
||||
but each part must be prefixed by its page name.
|
||||
.Xr usbhidctl 1 .
|
||||
.Pp
|
||||
The value is simply a numeric value.
|
||||
When the item reports this value,
|
||||
|
@ -280,12 +280,11 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore)
|
||||
char *p;
|
||||
int line;
|
||||
char buf[SIZE], name[SIZE], value[SIZE], debounce[SIZE], action[SIZE];
|
||||
char usbuf[SIZE], coll[SIZE];
|
||||
char usbuf[SIZE], coll[SIZE], *tmp;
|
||||
struct command *cmd, *cmds;
|
||||
struct hid_data *d;
|
||||
struct hid_item h;
|
||||
int u, lo, hi, range;
|
||||
|
||||
int inst, cinst, u, lo, hi, range, t;
|
||||
|
||||
f = fopen(conf, "r");
|
||||
if (f == NULL)
|
||||
@ -317,6 +316,12 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore)
|
||||
", syntax error: %s", conf, line, buf);
|
||||
}
|
||||
}
|
||||
tmp = strchr(name, '#');
|
||||
if (tmp != NULL) {
|
||||
*tmp = 0;
|
||||
inst = atoi(tmp + 1);
|
||||
} else
|
||||
inst = 0;
|
||||
|
||||
cmd = malloc(sizeof *cmd);
|
||||
if (cmd == NULL)
|
||||
@ -361,6 +366,7 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore)
|
||||
}
|
||||
|
||||
coll[0] = 0;
|
||||
cinst = 0;
|
||||
for (d = hid_start_parse(repd, 1 << hid_input, reportid);
|
||||
hid_get_item(d, &h); ) {
|
||||
if (verbose > 2)
|
||||
@ -380,24 +386,29 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore)
|
||||
range = 0;
|
||||
}
|
||||
for (u = lo; u <= hi; u++) {
|
||||
snprintf(usbuf, sizeof usbuf, "%s:%s",
|
||||
hid_usage_page(HID_PAGE(u)),
|
||||
hid_usage_in_page(u));
|
||||
if (verbose > 2)
|
||||
printf("usage %s\n", usbuf);
|
||||
if (!strcasecmp(usbuf, name))
|
||||
goto foundhid;
|
||||
if (coll[0]) {
|
||||
snprintf(usbuf, sizeof usbuf,
|
||||
"%s.%s:%s", coll+1,
|
||||
hid_usage_page(HID_PAGE(u)),
|
||||
hid_usage_page(HID_PAGE(u)),
|
||||
hid_usage_in_page(u));
|
||||
} else {
|
||||
snprintf(usbuf, sizeof usbuf,
|
||||
"%s:%s",
|
||||
hid_usage_page(HID_PAGE(u)),
|
||||
hid_usage_in_page(u));
|
||||
if (verbose > 2)
|
||||
printf("usage %s\n",
|
||||
usbuf);
|
||||
if (!strcasecmp(usbuf, name))
|
||||
goto foundhid;
|
||||
}
|
||||
if (verbose > 2)
|
||||
printf("usage %s\n", usbuf);
|
||||
t = strlen(usbuf) - strlen(name);
|
||||
if (t > 0) {
|
||||
if (strcmp(usbuf + t, name))
|
||||
continue;
|
||||
if (usbuf[t - 1] != '.')
|
||||
continue;
|
||||
} else if (strcmp(usbuf, name))
|
||||
continue;
|
||||
if (inst == cinst++)
|
||||
goto foundhid;
|
||||
}
|
||||
break;
|
||||
case hid_collection:
|
||||
|
@ -42,45 +42,141 @@
|
||||
#include <usbhid.h>
|
||||
#include <dev/usb/usbhid.h>
|
||||
|
||||
struct variable {
|
||||
char *name;
|
||||
int instance;
|
||||
int val;
|
||||
struct hid_item h;
|
||||
struct variable *next;
|
||||
} *vars;
|
||||
|
||||
int verbose = 0;
|
||||
int all = 0;
|
||||
int noname = 0;
|
||||
int hexdump = 0;
|
||||
int wflag = 0;
|
||||
int zflag = 0;
|
||||
|
||||
char **names;
|
||||
int nnames;
|
||||
static void usage(void);
|
||||
static void dumpitem(const char *label, struct hid_item *h);
|
||||
static void dumpitems(report_desc_t r);
|
||||
static void prdata(u_char *buf, struct hid_item *h);
|
||||
static void dumpdata(int f, report_desc_t r, int loop);
|
||||
static void writedata(int f, report_desc_t r);
|
||||
|
||||
void prbits(int bits, char **strs, int n);
|
||||
void usage(void);
|
||||
void dumpitem(const char *label, struct hid_item *h);
|
||||
void dumpitems(report_desc_t r);
|
||||
void rev(struct hid_item **p);
|
||||
void prdata(u_char *buf, struct hid_item *h);
|
||||
void dumpdata(int f, report_desc_t r, int loop);
|
||||
int gotname(char *n);
|
||||
|
||||
int
|
||||
gotname(char *n)
|
||||
static void
|
||||
parceargs(report_desc_t r, int all, int nnames, char **names)
|
||||
{
|
||||
int i;
|
||||
struct hid_data *d;
|
||||
struct hid_item h;
|
||||
char colls[1000];
|
||||
char hname[1000], *tmp1, *tmp2;
|
||||
struct variable *var, **pnext;
|
||||
int i, instance, cp, t;
|
||||
|
||||
for (i = 0; i < nnames; i++)
|
||||
if (strcmp(names[i], n) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
pnext = &vars;
|
||||
if (all) {
|
||||
if (wflag)
|
||||
errx(1, "Must not specify -w to read variables");
|
||||
cp = 0;
|
||||
for (d = hid_start_parse(r,
|
||||
1<<hid_input | 1<<hid_output | 1<<hid_feature, -1);
|
||||
hid_get_item(d, &h); ) {
|
||||
if (h.kind == hid_collection) {
|
||||
cp += sprintf(&colls[cp], "%s%s:%s",
|
||||
cp != 0 ? "." : "",
|
||||
hid_usage_page(HID_PAGE(h.usage)),
|
||||
hid_usage_in_page(h.usage));
|
||||
} else if (h.kind == hid_endcollection) {
|
||||
tmp1 = strrchr(colls, '.');
|
||||
if (tmp1 != NULL) {
|
||||
cp -= strlen(tmp1);
|
||||
tmp1[0] = 0;
|
||||
} else {
|
||||
cp = 0;
|
||||
colls[0] = 0;
|
||||
}
|
||||
}
|
||||
if ((h.kind != hid_input && h.kind != hid_output &&
|
||||
h.kind != hid_feature) || (h.flags & HIO_CONST))
|
||||
continue;
|
||||
var = malloc(sizeof(*var));
|
||||
memset(var, 0, sizeof(*var));
|
||||
asprintf(&var->name, "%s%s%s:%s",
|
||||
colls, colls[0] != 0 ? "." : "",
|
||||
hid_usage_page(HID_PAGE(h.usage)),
|
||||
hid_usage_in_page(h.usage));
|
||||
var->h = h;
|
||||
*pnext = var;
|
||||
pnext = &var->next;
|
||||
}
|
||||
hid_end_parse(d);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < nnames; i++) {
|
||||
var = malloc(sizeof(*var));
|
||||
memset(var, 0, sizeof(*var));
|
||||
tmp1 = tmp2 = strdup(names[i]);
|
||||
strsep(&tmp2, "=");
|
||||
var->name = strsep(&tmp1, "#");
|
||||
if (tmp1 != NULL)
|
||||
var->instance = atoi(tmp1);
|
||||
if (tmp2 != NULL) {
|
||||
if (!wflag)
|
||||
errx(1, "Must specify -w to write variables");
|
||||
var->val = atoi(tmp2);
|
||||
} else
|
||||
if (wflag)
|
||||
errx(1, "Must not specify -w to read variables");
|
||||
*pnext = var;
|
||||
pnext = &var->next;
|
||||
|
||||
instance = 0;
|
||||
cp = 0;
|
||||
for (d = hid_start_parse(r,
|
||||
1<<hid_input | 1<<hid_output | 1<<hid_feature, -1);
|
||||
hid_get_item(d, &h); ) {
|
||||
if (h.kind == hid_collection) {
|
||||
cp += sprintf(&colls[cp], "%s%s:%s",
|
||||
cp != 0 ? "." : "",
|
||||
hid_usage_page(HID_PAGE(h.usage)),
|
||||
hid_usage_in_page(h.usage));
|
||||
} else if (h.kind == hid_endcollection) {
|
||||
tmp1 = strrchr(colls, '.');
|
||||
if (tmp1 != NULL) {
|
||||
cp -= strlen(tmp1);
|
||||
tmp1[0] = 0;
|
||||
} else {
|
||||
cp = 0;
|
||||
colls[0] = 0;
|
||||
}
|
||||
}
|
||||
if ((h.kind != hid_input && h.kind != hid_output &&
|
||||
h.kind != hid_feature) || (h.flags & HIO_CONST))
|
||||
continue;
|
||||
snprintf(hname, sizeof(hname), "%s%s%s:%s",
|
||||
colls, colls[0] != 0 ? "." : "",
|
||||
hid_usage_page(HID_PAGE(h.usage)),
|
||||
hid_usage_in_page(h.usage));
|
||||
t = strlen(hname) - strlen(var->name);
|
||||
if (t > 0) {
|
||||
if (strcmp(hname + t, var->name) != 0)
|
||||
continue;
|
||||
if (hname[t - 1] != '.')
|
||||
continue;
|
||||
} else if (strcmp(hname, var->name) != 0)
|
||||
continue;
|
||||
if (var->instance != instance++)
|
||||
continue;
|
||||
var->h = h;
|
||||
break;
|
||||
}
|
||||
hid_end_parse(d);
|
||||
if (var->h.usage == 0)
|
||||
errx(1, "Unknown item '%s'", var->name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prbits(int bits, char **strs, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < n; i++, bits >>= 1)
|
||||
if (strs[i*2])
|
||||
printf("%s%s", i == 0 ? "" : ", ", strs[i*2 + (bits&1)]);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
@ -92,10 +188,14 @@ usage(void)
|
||||
" %s -f device "
|
||||
"[-l] [-n] [-r] [-t tablefile] [-v] [-x] -a\n",
|
||||
getprogname());
|
||||
fprintf(stderr,
|
||||
" %s -f device "
|
||||
"[-t tablefile] [-v] [-z] -w name=value\n",
|
||||
getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
dumpitem(const char *label, struct hid_item *h)
|
||||
{
|
||||
if ((h->flags & HIO_CONST) && !verbose)
|
||||
@ -134,7 +234,7 @@ hid_collection_type(int32_t type)
|
||||
return (num);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
dumpitems(report_desc_t r)
|
||||
{
|
||||
struct hid_data *d;
|
||||
@ -174,23 +274,7 @@ dumpitems(report_desc_t r)
|
||||
printf("Total feature size %d bytes\n", size);
|
||||
}
|
||||
|
||||
void
|
||||
rev(struct hid_item **p)
|
||||
{
|
||||
struct hid_item *cur, *prev, *next;
|
||||
|
||||
prev = 0;
|
||||
cur = *p;
|
||||
while(cur != 0) {
|
||||
next = cur->next;
|
||||
cur->next = prev;
|
||||
prev = cur;
|
||||
cur = next;
|
||||
}
|
||||
*p = prev;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
prdata(u_char *buf, struct hid_item *h)
|
||||
{
|
||||
u_int data;
|
||||
@ -212,82 +296,162 @@ prdata(u_char *buf, struct hid_item *h)
|
||||
h->pos = pos;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
dumpdata(int f, report_desc_t rd, int loop)
|
||||
{
|
||||
struct hid_data *d;
|
||||
struct hid_item h, *hids, *n;
|
||||
int r, dlen;
|
||||
struct variable *var;
|
||||
int dlen, havedata, i, match, r, rid, use_rid;
|
||||
u_char *dbuf;
|
||||
u_int32_t colls[100];
|
||||
int sp = 0;
|
||||
char namebuf[10000], *namep;
|
||||
enum hid_kind kind;
|
||||
|
||||
hids = 0;
|
||||
for (d = hid_start_parse(rd, 1<<hid_input, -1);
|
||||
hid_get_item(d, &h); ) {
|
||||
if (h.kind == hid_collection)
|
||||
colls[++sp] = h.usage;
|
||||
else if (h.kind == hid_endcollection)
|
||||
--sp;
|
||||
if (h.kind != hid_input || (h.flags & HIO_CONST))
|
||||
continue;
|
||||
h.next = hids;
|
||||
h.collection = colls[sp];
|
||||
hids = malloc(sizeof *hids);
|
||||
*hids = h;
|
||||
}
|
||||
hid_end_parse(d);
|
||||
rev(&hids);
|
||||
dlen = hid_report_size(rd, hid_input, -1);
|
||||
dbuf = malloc(dlen);
|
||||
if (!loop)
|
||||
if (hid_set_immed(f, 1) < 0) {
|
||||
if (errno == EOPNOTSUPP)
|
||||
warnx("device does not support immediate mode, only changes reported.");
|
||||
else
|
||||
err(1, "USB_SET_IMMED");
|
||||
}
|
||||
kind = 0;
|
||||
rid = -1;
|
||||
use_rid = !!hid_get_report_id(f);
|
||||
do {
|
||||
r = read(f, dbuf, dlen);
|
||||
if (r < 1) {
|
||||
err(1, "read error");
|
||||
}
|
||||
for (n = hids; n; n = n->next) {
|
||||
if (n->report_ID != 0 && dbuf[0] != n->report_ID)
|
||||
if (kind < 3) {
|
||||
if (++rid >= 256) {
|
||||
rid = 0;
|
||||
kind++;
|
||||
}
|
||||
if (kind >= 3)
|
||||
rid = -1;
|
||||
for (var = vars; var; var = var->next) {
|
||||
if (rid == var->h.report_ID &&
|
||||
kind == var->h.kind)
|
||||
break;
|
||||
}
|
||||
if (var == NULL)
|
||||
continue;
|
||||
namep = namebuf;
|
||||
namep += sprintf(namep, "%s:%s.",
|
||||
hid_usage_page(HID_PAGE(n->collection)),
|
||||
hid_usage_in_page(n->collection));
|
||||
namep += sprintf(namep, "%s:%s",
|
||||
hid_usage_page(HID_PAGE(n->usage)),
|
||||
hid_usage_in_page(n->usage));
|
||||
if (all || gotname(namebuf)) {
|
||||
if (!noname)
|
||||
printf("%s=", namebuf);
|
||||
prdata(dbuf, n);
|
||||
}
|
||||
dlen = hid_report_size(rd, kind < 3 ? kind : hid_input, rid);
|
||||
if (dlen <= 0)
|
||||
continue;
|
||||
dbuf = malloc(dlen);
|
||||
memset(dbuf, 0, dlen);
|
||||
if (kind < 3) {
|
||||
dbuf[0] = rid;
|
||||
r = hid_get_report(f, kind, dbuf, dlen);
|
||||
if (r < 0)
|
||||
warn("hid_get_report(rid %d)", rid);
|
||||
havedata = !r && (rid == 0 || dbuf[0] == rid);
|
||||
if (rid != 0)
|
||||
dbuf[0] = rid;
|
||||
} else {
|
||||
r = read(f, dbuf, dlen);
|
||||
if (r < 1)
|
||||
err(1, "read error");
|
||||
havedata = 1;
|
||||
}
|
||||
if (verbose) {
|
||||
printf("Got %s report %d (%d bytes):",
|
||||
kind == hid_output ? "output" :
|
||||
kind == hid_feature ? "feature" : "input",
|
||||
use_rid ? dbuf[0] : 0, dlen);
|
||||
if (havedata) {
|
||||
for (i = 0; i < dlen; i++)
|
||||
printf(" %02x", dbuf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
match = 0;
|
||||
for (var = vars; var; var = var->next) {
|
||||
if ((kind < 3 ? kind : hid_input) != var->h.kind)
|
||||
continue;
|
||||
if (var->h.report_ID != 0 &&
|
||||
dbuf[0] != var->h.report_ID)
|
||||
continue;
|
||||
match = 1;
|
||||
if (!noname)
|
||||
printf("%s=", var->name);
|
||||
if (havedata)
|
||||
prdata(dbuf, &var->h);
|
||||
printf("\n");
|
||||
}
|
||||
if (match)
|
||||
printf("\n");
|
||||
free(dbuf);
|
||||
} while (loop || kind < 3);
|
||||
}
|
||||
|
||||
static void
|
||||
writedata(int f, report_desc_t rd)
|
||||
{
|
||||
struct variable *var;
|
||||
int dlen, i, r, rid;
|
||||
u_char *dbuf;
|
||||
enum hid_kind kind;
|
||||
|
||||
kind = 0;
|
||||
rid = 0;
|
||||
for (kind = 0; kind < 3; kind ++) {
|
||||
for (rid = 0; rid < 256; rid ++) {
|
||||
for (var = vars; var; var = var->next) {
|
||||
if (rid == var->h.report_ID && kind == var->h.kind)
|
||||
break;
|
||||
}
|
||||
if (var == NULL)
|
||||
continue;
|
||||
dlen = hid_report_size(rd, kind, rid);
|
||||
if (dlen <= 0)
|
||||
continue;
|
||||
dbuf = malloc(dlen);
|
||||
memset(dbuf, 0, dlen);
|
||||
dbuf[0] = rid;
|
||||
if (!zflag && hid_get_report(f, kind, dbuf, dlen) == 0) {
|
||||
if (verbose) {
|
||||
printf("Got %s report %d (%d bytes):",
|
||||
kind == hid_input ? "input" :
|
||||
kind == hid_output ? "output" : "feature",
|
||||
rid, dlen);
|
||||
for (i = 0; i < dlen; i++)
|
||||
printf(" %02x", dbuf[i]);
|
||||
printf("\n");
|
||||
}
|
||||
} else if (!zflag) {
|
||||
warn("hid_get_report(rid %d)", rid);
|
||||
if (verbose) {
|
||||
printf("Can't get %s report %d (%d bytes). "
|
||||
"Will be initialized with zeros.\n",
|
||||
kind == hid_input ? "input" :
|
||||
kind == hid_output ? "output" : "feature",
|
||||
rid, dlen);
|
||||
}
|
||||
}
|
||||
if (loop)
|
||||
for (var = vars; var; var = var->next) {
|
||||
if (rid != var->h.report_ID || kind != var->h.kind)
|
||||
continue;
|
||||
hid_set_data(dbuf, &var->h, var->val);
|
||||
}
|
||||
if (verbose) {
|
||||
printf("Setting %s report %d (%d bytes):",
|
||||
kind == hid_output ? "output" :
|
||||
kind == hid_feature ? "feature" : "input",
|
||||
rid, dlen);
|
||||
for (i = 0; i < dlen; i++)
|
||||
printf(" %02x", dbuf[i]);
|
||||
printf("\n");
|
||||
} while (loop);
|
||||
free(dbuf);
|
||||
}
|
||||
r = hid_set_report(f, kind, dbuf, dlen);
|
||||
if (r != 0)
|
||||
warn("hid_set_report(rid %d)", rid);
|
||||
free(dbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int f;
|
||||
report_desc_t r;
|
||||
char devnam[100], *dev = 0;
|
||||
char *table = 0;
|
||||
char devnam[100], *dev = NULL;
|
||||
int f;
|
||||
int all = 0;
|
||||
int ch;
|
||||
int repdump = 0;
|
||||
int loop = 0;
|
||||
char *table = 0;
|
||||
|
||||
while ((ch = getopt(argc, argv, "af:lnrt:vx")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "af:lnrt:vwxz")) != -1) {
|
||||
switch(ch) {
|
||||
case 'a':
|
||||
all++;
|
||||
@ -310,9 +474,15 @@ main(int argc, char **argv)
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'w':
|
||||
wflag = 1;
|
||||
break;
|
||||
case 'x':
|
||||
hexdump = 1;
|
||||
break;
|
||||
case 'z':
|
||||
zflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
@ -320,12 +490,10 @@ main(int argc, char **argv)
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (dev == 0)
|
||||
if (dev == NULL)
|
||||
usage();
|
||||
names = argv;
|
||||
nnames = argc;
|
||||
|
||||
if (nnames == 0 && !all && !repdump)
|
||||
if (argc == 0 && !all && !repdump)
|
||||
usage();
|
||||
|
||||
if (dev[0] != '/') {
|
||||
@ -350,8 +518,13 @@ main(int argc, char **argv)
|
||||
printf("Report descriptor:\n");
|
||||
dumpitems(r);
|
||||
}
|
||||
if (nnames != 0 || all)
|
||||
dumpdata(f, r, loop);
|
||||
if (argc != 0 || all) {
|
||||
parceargs(r, all, argc, argv);
|
||||
if (wflag)
|
||||
writedata(f, r);
|
||||
else
|
||||
dumpdata(f, r, loop);
|
||||
}
|
||||
|
||||
hid_dispose_report_desc(r);
|
||||
exit(0);
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 23, 2006
|
||||
.Dd August 01, 2011
|
||||
.Dt USBHIDCTL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -36,27 +36,51 @@
|
||||
.Nd manipulate USB HID devices
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl a
|
||||
.Fl f Ar device
|
||||
.Op Fl l
|
||||
.Op Fl n
|
||||
.Op Fl r
|
||||
.Op Fl t Ar table
|
||||
.Op Fl v
|
||||
.Op Fl x
|
||||
.Op Ar item ...
|
||||
.Fl r
|
||||
.Nm
|
||||
.Fl f Ar device
|
||||
.Op Fl t Ar table
|
||||
.Op Fl l
|
||||
.Op Fl v
|
||||
.Op Fl x
|
||||
.Fl a
|
||||
.Nm
|
||||
.Fl f Ar device
|
||||
.Op Fl t Ar table
|
||||
.Op Fl l
|
||||
.Op Fl n
|
||||
.Op Fl v
|
||||
.Op Fl x
|
||||
.Ar item ...
|
||||
.Nm
|
||||
.Fl f Ar device
|
||||
.Op Fl t Ar table
|
||||
.Op Fl v
|
||||
.Op Fl z
|
||||
.Fl w
|
||||
.Ar item=value ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility can be used to dump the state of a USB HID (Human Interface Device).
|
||||
utility can be used to dump and modify the state of a USB HID (Human
|
||||
Interface Device).
|
||||
Each named
|
||||
.Ar item
|
||||
is printed.
|
||||
If the
|
||||
.Fl w
|
||||
flag is specified
|
||||
.Nm
|
||||
attempts to set the specified items to the given values.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a
|
||||
Show all items.
|
||||
Show all items and their current values if device returns.
|
||||
.It Fl f Ar device
|
||||
Specify a path name for the device to operate on.
|
||||
.It Fl l
|
||||
@ -69,9 +93,47 @@ Dump the report descriptor.
|
||||
Specify a path name for the HID usage table file.
|
||||
.It Fl v
|
||||
Be verbose.
|
||||
.It Fl w
|
||||
Change item values.
|
||||
Only 'output' and 'feature' kinds can be set with this option.
|
||||
.It Fl x
|
||||
Dump data in hexadecimal as well as decimal.
|
||||
.It Fl z
|
||||
Reset reports to zero before processing
|
||||
.Fl w
|
||||
arguments. If not specified, current values will be requested from device.
|
||||
.El
|
||||
.Sh SYNTAX
|
||||
.Nm
|
||||
compares the names of items specified on the command line against the human
|
||||
interface items reported by the USB device.
|
||||
Each human interface item is mapped from its native form to a human readable
|
||||
name, using the HID usage table file.
|
||||
Command line items are compared with the generated item names,
|
||||
and the USB HID device is operated on when a match is found.
|
||||
.Pp
|
||||
Each human interface item is named by the
|
||||
.Qq page
|
||||
it appears in, the
|
||||
.Qq usage
|
||||
within that page, and the list of
|
||||
.Qq collections
|
||||
containing the item.
|
||||
Each collection in turn is also identified by page, and
|
||||
the usage within that page.
|
||||
.Pp
|
||||
On the
|
||||
.Nm
|
||||
command line the page name is separated from the usage name with the character
|
||||
.Sq Cm \&: .
|
||||
The collections are separated by the character
|
||||
.Sq Cm \&. .
|
||||
.Pp
|
||||
Some devices give the same name to more than one item.
|
||||
.Nm
|
||||
supports isolating each item by appending a
|
||||
.Sq Cm \&# .
|
||||
character and a decimal item instance number, starting at zero.
|
||||
.Sh FILES
|
||||
.Pa /usr/share/misc/usb_hid_usages
|
||||
The default HID usage table.
|
||||
@ -84,7 +146,3 @@ The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Nx 1.4 .
|
||||
.Sh BUGS
|
||||
The
|
||||
.Nm
|
||||
utility cannot show nor set output and feature items.
|
||||
|
@ -345,7 +345,7 @@ ttyprt(struct xtty *xt)
|
||||
errx(1, "struct xtty size mismatch");
|
||||
if (usenumflag || xt->xt_dev == 0 ||
|
||||
(name = devname(xt->xt_dev, S_IFCHR)) == NULL)
|
||||
printf("%5d,%4d ", major(xt->xt_dev), minor(xt->xt_dev));
|
||||
printf("%#10jx ", (uintmax_t)xt->xt_dev);
|
||||
else
|
||||
printf("%10s ", name);
|
||||
printf("%5zu %4zu %4zu %4zu %5zu %4zu %4zu %5u %5d %5d ",
|
||||
|
Loading…
x
Reference in New Issue
Block a user