This commit is contained in:
attilio 2011-09-29 09:22:54 +00:00
parent ddd6ad1bba
commit e8310498d5
51 changed files with 1315 additions and 935 deletions

View File

@ -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 -> .

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 *

View File

@ -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"

View File

@ -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);
}

View File

@ -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

View File

@ -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:.*";

View File

@ -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])

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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 .

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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.");
}

View File

@ -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: ");
}

View File

@ -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; }

View File

@ -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

View File

@ -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

View File

@ -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];
}
}

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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 *);

View File

@ -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

View File

@ -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

View File

@ -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().

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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.

View File

@ -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,

View File

@ -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:

View File

@ -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);

View File

@ -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.

View File

@ -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 ",