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 .\" @(#)ls.1 8.7 (Berkeley) 7/29/94
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd April 4, 2008 .Dd September 28, 2011
.Dt LS 1 .Dt LS 1
.Os .Os
.Sh NAME .Sh NAME
@ -357,8 +357,7 @@ option is given,
the numeric ID's are displayed. the numeric ID's are displayed.
.Pp .Pp
If the file is a character special or block special file, If the file is a character special or block special file,
the major and minor device numbers for the file are displayed the device number for the file is displayed in the size field.
in the size field.
If the file is a symbolic link the pathname of the If the file is a symbolic link the pathname of the
linked-to file is preceded by linked-to file is preceded by
.Dq Li -> . .Dq Li -> .

View File

@ -563,7 +563,7 @@ display(const FTSENT *p, FTSENT *list, int options)
long maxblock; long maxblock;
u_long btotal, labelstrlen, maxinode, maxlen, maxnlink; u_long btotal, labelstrlen, maxinode, maxlen, maxnlink;
u_long maxlabelstr; u_long maxlabelstr;
u_int devstrlen; u_int sizelen;
int maxflags; int maxflags;
gid_t maxgroup; gid_t maxgroup;
uid_t maxuser; uid_t maxuser;
@ -572,7 +572,6 @@ display(const FTSENT *p, FTSENT *list, int options)
int entries, needstats; int entries, needstats;
const char *user, *group; const char *user, *group;
char *flags, *labelstr = NULL; char *flags, *labelstr = NULL;
char buf[STRBUF_SIZEOF(u_quad_t) + 1];
char ngroup[STRBUF_SIZEOF(uid_t) + 1]; char ngroup[STRBUF_SIZEOF(uid_t) + 1];
char nuser[STRBUF_SIZEOF(gid_t) + 1]; char nuser[STRBUF_SIZEOF(gid_t) + 1];
@ -656,7 +655,8 @@ display(const FTSENT *p, FTSENT *list, int options)
MAKENINES(maxsize); MAKENINES(maxsize);
free(jinitmax); free(jinitmax);
} }
devstrlen = 0; d.s_size = 0;
sizelen = 0;
flags = NULL; flags = NULL;
for (cur = list, entries = 0; cur; cur = cur->fts_link) { for (cur = list, entries = 0; cur; cur = cur->fts_link) {
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) { if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
@ -796,14 +796,12 @@ label_out:
np->group = &np->data[ulen + 1]; np->group = &np->data[ulen + 1];
(void)strcpy(np->group, group); (void)strcpy(np->group, group);
if ((S_ISCHR(sp->st_mode) || if (S_ISCHR(sp->st_mode) ||
S_ISBLK(sp->st_mode)) && S_ISBLK(sp->st_mode)) {
devstrlen < DEVSTR_HEX_LEN) { sizelen = snprintf(NULL, 0,
if (minor(sp->st_rdev) > 255 || "%#jx", (uintmax_t)sp->st_rdev);
minor(sp->st_rdev) < 0) if (d.s_size < sizelen)
devstrlen = DEVSTR_HEX_LEN; d.s_size = sizelen;
else
devstrlen = DEVSTR_LEN;
} }
if (f_flags) { if (f_flags) {
@ -837,23 +835,16 @@ label_out:
d.maxlen = maxlen; d.maxlen = maxlen;
if (needstats) { if (needstats) {
d.btotal = btotal; d.btotal = btotal;
(void)snprintf(buf, sizeof(buf), "%lu", maxblock); d.s_block = snprintf(NULL, 0, "%lu", maxblock);
d.s_block = strlen(buf);
d.s_flags = maxflags; d.s_flags = maxflags;
d.s_label = maxlabelstr; d.s_label = maxlabelstr;
d.s_group = maxgroup; d.s_group = maxgroup;
(void)snprintf(buf, sizeof(buf), "%lu", maxinode); d.s_inode = snprintf(NULL, 0, "%lu", maxinode);
d.s_inode = strlen(buf); d.s_nlink = snprintf(NULL, 0, "%lu", maxnlink);
(void)snprintf(buf, sizeof(buf), "%lu", maxnlink); sizelen = f_humanval ? HUMANVALSTR_LEN :
d.s_nlink = strlen(buf); snprintf(NULL, 0, "%ju", maxsize);
if (f_humanval) if (d.s_size < sizelen)
d.s_size = HUMANVALSTR_LEN; d.s_size = sizelen;
else {
(void)snprintf(buf, sizeof(buf), "%ju", maxsize);
d.s_size = strlen(buf);
}
if (d.s_size < devstrlen)
d.s_size = devstrlen;
d.s_user = maxuser; d.s_user = maxuser;
} }
printfcn(&d); printfcn(&d);

View File

@ -36,8 +36,6 @@
#define NO_PRINT 1 #define NO_PRINT 1
#define HUMANVALSTR_LEN 5 #define HUMANVALSTR_LEN 5
#define DEVSTR_LEN 8
#define DEVSTR_HEX_LEN 15
extern long blocksize; /* block size units */ extern long blocksize; /* block size units */

View File

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <langinfo.h> #include <langinfo.h>
#include <libutil.h> #include <libutil.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
@ -351,16 +352,8 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
static void static void
printdev(size_t width, dev_t dev) printdev(size_t width, dev_t dev)
{ {
char buf[DEVSTR_HEX_LEN + 1];
if (minor(dev) > 255 || minor(dev) < 0) (void)printf("%#*jx ", (u_int)width, (uintmax_t)dev);
(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);
} }
static void static void

View File

@ -39,63 +39,52 @@ extern fixpt_t ccpu;
extern int cflag, eval, fscale, nlistread, rawcpu; extern int cflag, eval, fscale, nlistread, rawcpu;
extern unsigned long mempages; extern unsigned long mempages;
extern time_t now; extern time_t now;
extern int showthreads, sumrusage, termwidth, totwidth; extern int showthreads, sumrusage, termwidth;
extern STAILQ_HEAD(velisthead, varent) varlist; extern STAILQ_HEAD(velisthead, varent) varlist;
__BEGIN_DECLS __BEGIN_DECLS
void arguments(KINFO *, VARENT *); char *arguments(KINFO *, VARENT *);
void command(KINFO *, VARENT *); char *command(KINFO *, VARENT *);
void cputime(KINFO *, VARENT *); char *cputime(KINFO *, VARENT *);
int donlist(void); int donlist(void);
void elapsed(KINFO *, VARENT *); char *elapsed(KINFO *, VARENT *);
void elapseds(KINFO *, VARENT *); char *elapseds(KINFO *, VARENT *);
void emulname(KINFO *, VARENT *); char *emulname(KINFO *, VARENT *);
VARENT *find_varentry(VAR *); VARENT *find_varentry(VAR *);
const char *fmt_argv(char **, char *, size_t); const char *fmt_argv(char **, char *, size_t);
double getpcpu(const KINFO *); double getpcpu(const KINFO *);
void kvar(KINFO *, VARENT *); char *kvar(KINFO *, VARENT *);
void label(KINFO *, VARENT *); char *label(KINFO *, VARENT *);
void loginclass(KINFO *, VARENT *); char *loginclass(KINFO *, VARENT *);
void logname(KINFO *, VARENT *); char *logname(KINFO *, VARENT *);
void longtname(KINFO *, VARENT *); char *longtname(KINFO *, VARENT *);
void lstarted(KINFO *, VARENT *); char *lstarted(KINFO *, VARENT *);
void maxrss(KINFO *, VARENT *); char *maxrss(KINFO *, VARENT *);
void lockname(KINFO *, VARENT *); char *lockname(KINFO *, VARENT *);
void mwchan(KINFO *, VARENT *); char *mwchan(KINFO *, VARENT *);
void nwchan(KINFO *, VARENT *); char *nwchan(KINFO *, VARENT *);
void pagein(KINFO *, VARENT *); char *pagein(KINFO *, VARENT *);
void parsefmt(const char *, int); void parsefmt(const char *, int);
void pcpu(KINFO *, VARENT *); char *pcpu(KINFO *, VARENT *);
void pmem(KINFO *, VARENT *); char *pmem(KINFO *, VARENT *);
void pri(KINFO *, VARENT *); char *pri(KINFO *, VARENT *);
void printheader(void); void printheader(void);
void priorityr(KINFO *, VARENT *); char *priorityr(KINFO *, VARENT *);
void egroupname(KINFO *, VARENT *); char *egroupname(KINFO *, VARENT *);
void rgroupname(KINFO *, VARENT *); char *rgroupname(KINFO *, VARENT *);
void runame(KINFO *, VARENT *); char *runame(KINFO *, VARENT *);
void rvar(KINFO *, VARENT *); char *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 *);
void showkey(void); void showkey(void);
void started(KINFO *, VARENT *); char *started(KINFO *, VARENT *);
void state(KINFO *, VARENT *); char *state(KINFO *, VARENT *);
void systime(KINFO *, VARENT *); char *systime(KINFO *, VARENT *);
void tdev(KINFO *, VARENT *); char *tdev(KINFO *, VARENT *);
void tdnam(KINFO *, VARENT *); char *tdnam(KINFO *, VARENT *);
void tname(KINFO *, VARENT *); char *tname(KINFO *, VARENT *);
void ucomm(KINFO *, VARENT *); char *ucomm(KINFO *, VARENT *);
void uname(KINFO *, VARENT *); char *uname(KINFO *, VARENT *);
void upr(KINFO *, VARENT *); char *upr(KINFO *, VARENT *);
void usertime(KINFO *, VARENT *); char *usertime(KINFO *, VARENT *);
void vsize(KINFO *, VARENT *); char *vsize(KINFO *, VARENT *);
void wchan(KINFO *, VARENT *); char *wchan(KINFO *, VARENT *);
__END_DECLS __END_DECLS

View File

@ -57,178 +57,116 @@ static int vcmp(const void *, const void *);
#define KOFF(x) offsetof(struct kinfo_proc, x) #define KOFF(x) offsetof(struct kinfo_proc, x)
#define ROFF(x) offsetof(struct rusage, x) #define ROFF(x) offsetof(struct rusage, x)
#define EMULLEN 13 /* enough for "FreeBSD ELF32" */
#define LWPFMT "d" #define LWPFMT "d"
#define LWPLEN 6
#define NLWPFMT "d" #define NLWPFMT "d"
#define NLWPLEN 4
#define UIDFMT "u" #define UIDFMT "u"
#define UIDLEN 5
#define PIDFMT "d" #define PIDFMT "d"
#define PIDLEN 5
#define USERLEN (MAXLOGNAME - 1)
/* PLEASE KEEP THE TABLE BELOW SORTED ALPHABETICALLY!!! */ /* PLEASE KEEP THE TABLE BELOW SORTED ALPHABETICALLY!!! */
static VAR var[] = { static VAR var[] = {
{"%cpu", "%CPU", NULL, 0, pcpu, NULL, 5, 0, CHAR, NULL, 0}, {"%cpu", "%CPU", NULL, 0, pcpu, 0, CHAR, NULL, 0},
{"%mem", "%MEM", NULL, 0, pmem, NULL, 4, 0, CHAR, NULL, 0}, {"%mem", "%MEM", NULL, 0, pmem, 0, CHAR, NULL, 0},
{"acflag", "ACFLG", NULL, 0, kvar, NULL, 3, KOFF(ki_acflag), USHORT, {"acflag", "ACFLG", NULL, 0, kvar, KOFF(ki_acflag), USHORT, "x", 0},
"x", 0}, {"acflg", "", "acflag", 0, NULL, 0, CHAR, NULL, 0},
{"acflg", "", "acflag", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"args", "COMMAND", NULL, COMM|LJUST|USER, arguments, 0,
{"args", "COMMAND", NULL, COMM|LJUST|USER, arguments, NULL, 16, 0,
CHAR, NULL, 0}, CHAR, NULL, 0},
{"blocked", "", "sigmask", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"blocked", "", "sigmask", 0, NULL, 0, CHAR, NULL, 0},
{"caught", "", "sigcatch", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"caught", "", "sigcatch", 0, NULL, 0, CHAR, NULL, 0},
{"class", "CLASS", NULL, LJUST, loginclass, s_loginclass, {"class", "CLASS", NULL, LJUST, loginclass, 0, CHAR, NULL, 0},
MAXLOGNAME-1, 0, CHAR, NULL, 0}, {"comm", "COMMAND", NULL, LJUST, ucomm, 0, CHAR, NULL, 0},
{"comm", "COMMAND", NULL, LJUST, ucomm, s_comm, {"command", "COMMAND", NULL, COMM|LJUST|USER, command, 0,
COMMLEN + TDNAMLEN + 1, 0, CHAR, NULL, 0},
{"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16, 0,
CHAR, NULL, 0}, CHAR, NULL, 0},
{"cpu", "CPU", NULL, 0, kvar, NULL, 3, KOFF(ki_estcpu), UINT, "d", {"cpu", "CPU", NULL, 0, kvar, KOFF(ki_estcpu), UINT, "d", 0},
0}, {"cputime", "", "time", 0, NULL, 0, CHAR, NULL, 0},
{"cputime", "", "time", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"egid", "", "gid", 0, NULL, 0, CHAR, NULL, 0},
{"egid", "", "gid", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"egroup", "", "group", 0, NULL, 0, CHAR, NULL, 0},
{"egroup", "", "group", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"emul", "EMUL", NULL, LJUST, emulname, 0, CHAR, NULL, 0},
{"emul", "EMUL", NULL, LJUST, emulname, NULL, EMULLEN, 0, CHAR, {"etime", "ELAPSED", NULL, USER, elapsed, 0, CHAR, NULL, 0},
NULL, 0}, {"etimes", "ELAPSED", NULL, USER, elapseds, 0, CHAR, NULL, 0},
{"etime", "ELAPSED", NULL, USER, elapsed, NULL, 12, 0, CHAR, NULL, 0}, {"euid", "", "uid", 0, NULL, 0, CHAR, NULL, 0},
{"etimes", "ELAPSED", NULL, USER, elapseds, NULL, 12, 0, CHAR, NULL, 0}, {"f", "F", NULL, 0, kvar, KOFF(ki_flag), INT, "x", 0},
{"euid", "", "uid", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"flags", "", "f", 0, NULL, 0, CHAR, NULL, 0},
{"f", "F", NULL, 0, kvar, NULL, 8, KOFF(ki_flag), INT, "x", 0}, {"gid", "GID", NULL, 0, kvar, KOFF(ki_groups), UINT, UIDFMT, 0},
{"flags", "", "f", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"group", "GROUP", NULL, LJUST, egroupname, 0, CHAR, NULL, 0},
{"gid", "GID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_groups), {"ignored", "", "sigignore", 0, NULL, 0, CHAR, NULL, 0},
UINT, UIDFMT, 0}, {"inblk", "INBLK", NULL, USER, rvar, ROFF(ru_inblock), LONG, "ld", 0},
{"group", "GROUP", NULL, LJUST, egroupname, s_egroupname, {"inblock", "", "inblk", 0, NULL, 0, CHAR, NULL, 0},
USERLEN, 0, CHAR, NULL, 0}, {"jid", "JID", NULL, 0, kvar, KOFF(ki_jid), INT, "d", 0},
{"ignored", "", "sigignore", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"jobc", "JOBC", NULL, 0, kvar, KOFF(ki_jobc), SHORT, "d", 0},
{"inblk", "INBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_inblock), LONG, {"ktrace", "KTRACE", NULL, 0, kvar, KOFF(ki_traceflag), INT, "x", 0},
"ld", 0}, {"label", "LABEL", NULL, LJUST, label, 0, CHAR, NULL, 0},
{"inblock", "", "inblk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"lim", "LIM", NULL, 0, maxrss, 0, CHAR, NULL, 0},
{"jid", "JID", NULL, 0, kvar, NULL, 6, KOFF(ki_jid), INT, "d", 0}, {"lockname", "LOCK", NULL, LJUST, lockname, 0, CHAR, NULL, 0},
{"jobc", "JOBC", NULL, 0, kvar, NULL, 4, KOFF(ki_jobc), SHORT, "d", {"login", "LOGIN", NULL, LJUST, logname, 0, CHAR, NULL, 0},
0}, {"logname", "", "login", 0, NULL, 0, CHAR, NULL, 0},
{"ktrace", "KTRACE", NULL, 0, kvar, NULL, 8, KOFF(ki_traceflag), INT, {"lstart", "STARTED", NULL, LJUST|USER, lstarted, 0, CHAR, NULL, 0},
"x", 0}, {"lwp", "LWP", NULL, 0, kvar, KOFF(ki_tid), UINT, LWPFMT, 0},
{"label", "LABEL", NULL, LJUST, label, s_label, SHRT_MAX, 0, CHAR, {"majflt", "MAJFLT", NULL, USER, rvar, ROFF(ru_majflt), LONG, "ld", 0},
NULL, 0}, {"minflt", "MINFLT", NULL, USER, rvar, ROFF(ru_minflt), LONG, "ld", 0},
{"lim", "LIM", NULL, 0, maxrss, NULL, 5, 0, CHAR, NULL, 0}, {"msgrcv", "MSGRCV", NULL, USER, rvar, ROFF(ru_msgrcv), LONG, "ld", 0},
{"lockname", "LOCK", NULL, LJUST, lockname, NULL, 6, 0, CHAR, NULL, {"msgsnd", "MSGSND", NULL, USER, rvar, ROFF(ru_msgsnd), LONG, "ld", 0},
0}, {"mwchan", "MWCHAN", NULL, LJUST, mwchan, 0, CHAR, NULL, 0},
{"login", "LOGIN", NULL, LJUST, logname, s_logname, MAXLOGNAME-1, {"ni", "", "nice", 0, NULL, 0, CHAR, NULL, 0},
0, CHAR, NULL, 0}, {"nice", "NI", NULL, 0, kvar, KOFF(ki_nice), CHAR, "d", 0},
{"logname", "", "login", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"nivcsw", "NIVCSW", NULL, USER, rvar, ROFF(ru_nivcsw), LONG, "ld", 0},
{"lstart", "STARTED", NULL, LJUST|USER, lstarted, NULL, 28, 0, CHAR, {"nlwp", "NLWP", NULL, 0, kvar, KOFF(ki_numthreads), UINT, NLWPFMT, 0},
NULL, 0}, {"nsignals", "", "nsigs", 0, NULL, 0, CHAR, NULL, 0},
{"lwp", "LWP", NULL, 0, kvar, NULL, LWPLEN, KOFF(ki_tid), UINT, {"nsigs", "NSIGS", NULL, USER, rvar, ROFF(ru_nsignals), LONG, "ld", 0},
LWPFMT, 0}, {"nswap", "NSWAP", NULL, USER, rvar, ROFF(ru_nswap), LONG, "ld", 0},
{"majflt", "MAJFLT", NULL, USER, rvar, NULL, 4, ROFF(ru_majflt), {"nvcsw", "NVCSW", NULL, USER, rvar, ROFF(ru_nvcsw), LONG, "ld", 0},
LONG, "ld", 0}, {"nwchan", "NWCHAN", NULL, LJUST, nwchan, 0, CHAR, NULL, 0},
{"minflt", "MINFLT", NULL, USER, rvar, NULL, 4, ROFF(ru_minflt), {"oublk", "OUBLK", NULL, USER, rvar, ROFF(ru_oublock), LONG, "ld", 0},
LONG, "ld", 0}, {"oublock", "", "oublk", 0, NULL, 0, CHAR, NULL, 0},
{"msgrcv", "MSGRCV", NULL, USER, rvar, NULL, 4, ROFF(ru_msgrcv), {"paddr", "PADDR", NULL, 0, kvar, KOFF(ki_paddr), KPTR, "lx", 0},
LONG, "ld", 0}, {"pagein", "PAGEIN", NULL, USER, pagein, 0, CHAR, NULL, 0},
{"msgsnd", "MSGSND", NULL, USER, rvar, NULL, 4, ROFF(ru_msgsnd), {"pcpu", "", "%cpu", 0, NULL, 0, CHAR, NULL, 0},
LONG, "ld", 0}, {"pending", "", "sig", 0, NULL, 0, CHAR, NULL, 0},
{"mwchan", "MWCHAN", NULL, LJUST, mwchan, NULL, 6, 0, CHAR, NULL, 0}, {"pgid", "PGID", NULL, 0, kvar, KOFF(ki_pgid), UINT, PIDFMT, 0},
{"ni", "", "nice", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"pid", "PID", NULL, 0, kvar, KOFF(ki_pid), UINT, PIDFMT, 0},
{"nice", "NI", NULL, 0, kvar, NULL, 2, KOFF(ki_nice), CHAR, "d", {"pmem", "", "%mem", 0, NULL, 0, CHAR, NULL, 0},
0}, {"ppid", "PPID", NULL, 0, kvar, KOFF(ki_ppid), UINT, PIDFMT, 0},
{"nivcsw", "NIVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nivcsw), {"pri", "PRI", NULL, 0, pri, 0, CHAR, NULL, 0},
LONG, "ld", 0}, {"re", "RE", NULL, INF127, kvar, KOFF(ki_swtime), UINT, "d", 0},
{"nlwp", "NLWP", NULL, 0, kvar, NULL, NLWPLEN, KOFF(ki_numthreads), {"rgid", "RGID", NULL, 0, kvar, KOFF(ki_rgid), UINT, UIDFMT, 0},
UINT, NLWPFMT, 0}, {"rgroup", "RGROUP", NULL, LJUST, rgroupname, 0, CHAR, NULL, 0},
{"nsignals", "", "nsigs", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"rss", "RSS", NULL, 0, kvar, KOFF(ki_rssize), PGTOK, "ld", 0},
{"nsigs", "NSIGS", NULL, USER, rvar, NULL, 4, ROFF(ru_nsignals), {"rtprio", "RTPRIO", NULL, 0, priorityr, KOFF(ki_pri), CHAR, NULL, 0},
LONG, "ld", 0}, {"ruid", "RUID", NULL, 0, kvar, KOFF(ki_ruid), UINT, UIDFMT, 0},
{"nswap", "NSWAP", NULL, USER, rvar, NULL, 4, ROFF(ru_nswap), {"ruser", "RUSER", NULL, LJUST, runame, 0, CHAR, NULL, 0},
LONG, "ld", 0}, {"sid", "SID", NULL, 0, kvar, KOFF(ki_sid), UINT, PIDFMT, 0},
{"nvcsw", "NVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw), {"sig", "PENDING", NULL, 0, kvar, KOFF(ki_siglist), INT, "x", 0},
LONG, "ld", 0}, {"sigcatch", "CAUGHT", NULL, 0, kvar, KOFF(ki_sigcatch), UINT, "x", 0},
{"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, sizeof(void *) * 2, 0, {"sigignore", "IGNORED", NULL, 0, kvar, KOFF(ki_sigignore),
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),
UINT, "x", 0}, UINT, "x", 0},
{"sigignore", "IGNORED", NULL, 0, kvar, NULL, 8, KOFF(ki_sigignore), {"sigmask", "BLOCKED", NULL, 0, kvar, KOFF(ki_sigmask), UINT, "x", 0},
UINT, "x", 0}, {"sl", "SL", NULL, INF127, kvar, KOFF(ki_slptime), UINT, "d", 0},
{"sigmask", "BLOCKED", NULL, 0, kvar, NULL, 8, KOFF(ki_sigmask), {"start", "STARTED", NULL, LJUST|USER, started, 0, CHAR, NULL, 0},
UINT, "x", 0}, {"stat", "", "state", 0, NULL, 0, CHAR, NULL, 0},
{"sl", "SL", NULL, INF127, kvar, NULL, 3, KOFF(ki_slptime), UINT, "d", {"state", "STAT", NULL, LJUST, state, 0, CHAR, NULL, 0},
0}, {"svgid", "SVGID", NULL, 0, kvar, KOFF(ki_svgid), UINT, UIDFMT, 0},
{"start", "STARTED", NULL, LJUST|USER, started, NULL, 7, 0, CHAR, NULL, {"svuid", "SVUID", NULL, 0, kvar, KOFF(ki_svuid), UINT, UIDFMT, 0},
0}, {"systime", "SYSTIME", NULL, USER, systime, 0, CHAR, NULL, 0},
{"stat", "", "state", 0, NULL, NULL, 0, 0, CHAR, NULL, 0}, {"tdaddr", "TDADDR", NULL, 0, kvar, KOFF(ki_tdaddr), KPTR, "lx", 0},
{"state", "STAT", NULL, 0, state, NULL, 4, 0, CHAR, NULL, 0}, {"tdev", "TDEV", NULL, 0, tdev, 0, CHAR, NULL, 0},
{"svgid", "SVGID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_svgid), {"tdnam", "TDNAM", NULL, LJUST, tdnam, 0, CHAR, NULL, 0},
UINT, UIDFMT, 0}, {"time", "TIME", NULL, USER, cputime, 0, CHAR, NULL, 0},
{"svuid", "SVUID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_svuid), {"tpgid", "TPGID", NULL, 0, kvar, KOFF(ki_tpgid), UINT, PIDFMT, 0},
UINT, UIDFMT, 0}, {"tsid", "TSID", NULL, 0, kvar, KOFF(ki_tsid), UINT, PIDFMT, 0},
{"systime", "SYSTIME", NULL, USER, systime, s_systime, 15, 0, CHAR, {"tsiz", "TSIZ", NULL, 0, kvar, KOFF(ki_tsize), PGTOK, "ld", 0},
NULL, 0}, {"tt", "TT ", NULL, 0, tname, 0, CHAR, NULL, 0},
{"tdaddr", "TDADDR", NULL, 0, kvar, NULL, sizeof(void *) * 2, {"tty", "TTY", NULL, LJUST, longtname, 0, CHAR, NULL, 0},
KOFF(ki_tdaddr), KPTR, "lx", 0}, {"ucomm", "UCOMM", NULL, LJUST, ucomm, 0, CHAR, NULL, 0},
{"tdev", "TDEV", NULL, 0, tdev, NULL, 5, 0, CHAR, NULL, 0}, {"uid", "UID", NULL, 0, kvar, KOFF(ki_uid), UINT, UIDFMT, 0},
{"tdnam", "TDNAM", NULL, LJUST, tdnam, NULL, COMMLEN, 0, CHAR, NULL, 0}, {"upr", "UPR", NULL, 0, upr, 0, CHAR, NULL, 0},
{"time", "TIME", NULL, USER, cputime, s_cputime, 15, 0, CHAR, {"uprocp", "UPROCP", NULL, 0, kvar, KOFF(ki_paddr), KPTR, "lx", 0},
NULL, 0}, {"user", "USER", NULL, LJUST, uname, 0, CHAR, NULL, 0},
{"tpgid", "TPGID", NULL, 0, kvar, NULL, 4, KOFF(ki_tpgid), UINT, {"usertime", "USERTIME", NULL, USER, usertime, 0, CHAR, NULL, 0},
PIDFMT, 0}, {"usrpri", "", "upr", 0, NULL, 0, CHAR, NULL, 0},
{"tsid", "TSID", NULL, 0, kvar, NULL, PIDLEN, KOFF(ki_tsid), UINT, {"vsize", "", "vsz", 0, NULL, 0, CHAR, NULL, 0},
PIDFMT, 0}, {"vsz", "VSZ", NULL, 0, vsize, 0, CHAR, NULL, 0},
{"tsiz", "TSIZ", NULL, 0, kvar, NULL, 4, KOFF(ki_tsize), PGTOK, "ld", 0}, {"wchan", "WCHAN", NULL, LJUST, wchan, 0, CHAR, NULL, 0},
{"tt", "TT ", NULL, 0, tname, NULL, 4, 0, CHAR, NULL, 0}, {"xstat", "XSTAT", NULL, 0, kvar, KOFF(ki_xstat), USHORT, "x", 0},
{"tty", "TTY", NULL, LJUST, longtname, NULL, 8, 0, CHAR, NULL, 0}, {"", NULL, NULL, 0, NULL, 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},
}; };
void 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 rawcpu; /* -C */
int sumrusage; /* -S */ int sumrusage; /* -S */
int termwidth; /* Width of the screen (0 == infinity). */ int termwidth; /* Width of the screen (0 == infinity). */
int totwidth; /* Calculated-width of requested variables. */
int showthreads; /* will threads be shown? */ int showthreads; /* will threads be shown? */
struct velisthead varlist = STAILQ_HEAD_INITIALIZER(varlist); struct velisthead varlist = STAILQ_HEAD_INITIALIZER(varlist);
static int forceuread = DEF_UREAD; /* Do extra work to get u-area. */ static int forceuread = DEF_UREAD; /* Do extra work to get u-area. */
static kvm_t *kd; static kvm_t *kd;
static KINFO *kinfo;
static int needcomm; /* -o "command" */ static int needcomm; /* -o "command" */
static int needenv; /* -e */ static int needenv; /* -e */
static int needuser; /* -o "user" */ 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 int addelem_uid(struct listinfo *, const char *);
static void add_list(struct listinfo *, const char *); static void add_list(struct listinfo *, const char *);
static void descendant_sort(KINFO *, int); static void descendant_sort(KINFO *, int);
static void dynsizevars(KINFO *); static void format_output(KINFO *);
static void *expand_list(struct listinfo *); static void *expand_list(struct listinfo *);
static const char * static const char *
fmt(char **(*)(kvm_t *, const struct kinfo_proc *, int), 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 gidlist, pgrplist, pidlist;
struct listinfo ruidlist, sesslist, ttylist, uidlist; struct listinfo ruidlist, sesslist, ttylist, uidlist;
struct kinfo_proc *kp; struct kinfo_proc *kp;
KINFO *next_KINFO; KINFO *kinfo = NULL, *next_KINFO;
KINFO_STR *ks;
struct varent *vent; struct varent *vent;
struct winsize ws; struct winsize ws;
const char *nlistf, *memf; const char *nlistf, *memf, *fmtstr, *str;
char *cols; 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 descendancy, nentries, nkept, nselectors;
int prtheader, wflag, what, xkeep, xkeep_implied; int prtheader, wflag, what, xkeep, xkeep_implied;
char errbuf[_POSIX2_LINE_MAX]; char errbuf[_POSIX2_LINE_MAX];
@ -588,19 +587,16 @@ main(int argc, char *argv[])
kp->ki_dsize + kp->ki_ssize; kp->ki_dsize + kp->ki_ssize;
if (needuser) if (needuser)
saveuser(next_KINFO); saveuser(next_KINFO);
dynsizevars(next_KINFO);
nkept++; nkept++;
} }
} }
sizevars(); sizevars();
/* if (nkept == 0) {
* print header printheader();
*/
printheader();
if (nkept == 0)
exit(1); exit(1);
}
/* /*
* sort proc list * sort proc list
@ -613,14 +609,59 @@ main(int argc, char *argv[])
if (descendancy) if (descendancy)
descendant_sort(kinfo, nkept); 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++) { for (i = lineno = 0; i < nkept; i++) {
linelen = 0;
STAILQ_FOREACH(vent, &varlist, next_ve) { STAILQ_FOREACH(vent, &varlist, next_ve) {
(vent->var->oproc)(&kinfo[i], vent); if (vent->var->flag & LJUST)
if (STAILQ_NEXT(vent, next_ve) != NULL) 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(' '); (void)putchar(' ');
linelen++;
}
} }
(void)putchar('\n'); (void)putchar('\n');
if (prtheader && lineno++ == prtheader - 4) { if (prtheader && lineno++ == prtheader - 4) {
@ -1078,10 +1119,6 @@ scanvars(void)
STAILQ_FOREACH(vent, &varlist, next_ve) { STAILQ_FOREACH(vent, &varlist, next_ve) {
v = vent->var; v = vent->var;
if (v->sproc != NULL) {
v->dwidth = v->width;
v->width = 0;
}
if (v->flag & USER) if (v->flag & USER)
needuser = 1; needuser = 1;
if (v->flag & COMM) if (v->flag & COMM)
@ -1090,21 +1127,29 @@ scanvars(void)
} }
static void static void
dynsizevars(KINFO *ki) format_output(KINFO *ki)
{ {
struct varent *vent; struct varent *vent;
VAR *v; VAR *v;
int i; KINFO_STR *ks;
char *str;
int len;
STAILQ_INIT(&ki->ki_ks);
STAILQ_FOREACH(vent, &varlist, next_ve) { STAILQ_FOREACH(vent, &varlist, next_ve) {
v = vent->var; v = vent->var;
if (v->sproc == NULL) str = (v->oproc)(ki, vent);
continue; ks = malloc(sizeof(*ks));
i = (v->sproc)(ki); if (ks == NULL)
if (v->width < i) errx(1, "malloc failed");
v->width = i; ks->ks_str = str;
if (v->width > v->dwidth) STAILQ_INSERT_TAIL(&ki->ki_ks, ks, ks_next);
v->width = v->dwidth; 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); i = strlen(vent->header);
if (v->width < i) if (v->width < i)
v->width = i; v->width = i;
totwidth += v->width + 1; /* +1 for space */
} }
totwidth--;
} }
static const char * static const char *

View File

@ -35,6 +35,11 @@
#define UNLIMITED 0 /* unlimited terminal width */ #define UNLIMITED 0 /* unlimited terminal width */
enum type { CHAR, UCHAR, SHORT, USHORT, INT, UINT, LONG, ULONG, KPTR, PGTOK }; 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 { typedef struct kinfo {
struct kinfo_proc *ki_p; /* kinfo_proc structure */ struct kinfo_proc *ki_p; /* kinfo_proc structure */
char *ki_args; /* exec args */ char *ki_args; /* exec args */
@ -46,6 +51,7 @@ typedef struct kinfo {
int level; /* used in decendant_sort() */ int level; /* used in decendant_sort() */
char *prefix; /* calculated in decendant_sort() */ char *prefix; /* calculated in decendant_sort() */
} ki_d; } ki_d;
STAILQ_HEAD(, kinfo_str) ki_ks;
} KINFO; } KINFO;
/* Variables. */ /* Variables. */
@ -65,10 +71,7 @@ typedef struct var {
#define INF127 0x10 /* values >127 displayed as 127 */ #define INF127 0x10 /* values >127 displayed as 127 */
u_int flag; u_int flag;
/* output routine */ /* output routine */
void (*oproc)(struct kinfo *, struct varent *); char *(*oproc)(struct kinfo *, struct varent *);
/* sizing routine */
int (*sproc)(struct kinfo *);
short width; /* printing width */
/* /*
* The following (optional) elements are hooks for passing information * The following (optional) elements are hooks for passing information
* to the generic output routine pvar (which prints simple elements * to the generic output routine pvar (which prints simple elements
@ -77,10 +80,8 @@ typedef struct var {
size_t off; /* offset in structure */ size_t off; /* offset in structure */
enum type type; /* type of element */ enum type type; /* type of element */
const char *fmt; /* printf format */ const char *fmt; /* printf format */
short dwidth; /* dynamic printing width */
/* short width; /* calculated width */
* glue to link selected fields together
*/
} VAR; } VAR;
#include "extern.h" #include "extern.h"

View File

@ -467,7 +467,6 @@ change_one(zfs_handle_t *zhp, void *data)
* This is necessary when the original mountpoint * This is necessary when the original mountpoint
* is legacy or none. * is legacy or none.
*/ */
ASSERT(!clp->cl_alldependents);
verify(uu_list_insert_before(clp->cl_list, verify(uu_list_insert_before(clp->cl_list,
uu_list_first(clp->cl_list), cn) == 0); 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: * 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$ * $FreeBSD$
*/ */
@ -58,6 +58,7 @@
#define buffer_get_int64 ssh_buffer_get_int64 #define buffer_get_int64 ssh_buffer_get_int64
#define buffer_get_int64_ret ssh_buffer_get_int64_ret #define buffer_get_int64_ret ssh_buffer_get_int64_ret
#define buffer_get_int_ret ssh_buffer_get_int_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_ret ssh_buffer_get_ret
#define buffer_get_short ssh_buffer_get_short #define buffer_get_short ssh_buffer_get_short
#define buffer_get_short_ret ssh_buffer_get_short_ret #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_send_window_changes ssh_channel_send_window_changes
#define channel_set_af ssh_channel_set_af #define channel_set_af ssh_channel_set_af
#define channel_set_fds ssh_channel_set_fds #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_local_fwd_listener ssh_channel_setup_local_fwd_listener
#define channel_setup_remote_fwd_listener ssh_channel_setup_remote_fwd_listener #define channel_setup_remote_fwd_listener ssh_channel_setup_remote_fwd_listener
#define channel_still_open ssh_channel_still_open #define channel_still_open ssh_channel_still_open
@ -438,6 +440,7 @@
#define set_nonblock ssh_set_nonblock #define set_nonblock ssh_set_nonblock
#define shadow_pw ssh_shadow_pw #define shadow_pw ssh_shadow_pw
#define sigdie ssh_sigdie #define sigdie ssh_sigdie
#define sock_get_rcvbuf ssh_sock_get_rcvbuf
#define sock_set_v6only ssh_sock_set_v6only #define sock_set_v6only ssh_sock_set_v6only
#define ssh1_3des_iv ssh_ssh1_3des_iv #define ssh1_3des_iv ssh_ssh1_3des_iv
#define start_progress_meter ssh_start_progress_meter #define start_progress_meter ssh_start_progress_meter

View File

@ -8,10 +8,10 @@
# NB: device-name is shorthand for 'match device-name' # NB: device-name is shorthand for 'match device-name'
options { options {
# Each directory directive adds a directory the list of directories # Each "directory" directive adds a directory to the list of
# that we scan for files. Files are read-in in the order that they # directories that we scan for files. Files are loaded in the order
# are returned from readdir(3). The rule-sets are combined to # that they are returned from readdir(3). The rule-sets are combined
# create a DFA that's used to match events to actions. # to create a DFA that's used to match events to actions.
directory "/etc/devd"; directory "/etc/devd";
directory "/usr/local/etc/devd"; directory "/usr/local/etc/devd";
pid-file "/var/run/devd.pid"; pid-file "/var/run/devd.pid";
@ -32,8 +32,8 @@ options {
# script is called pccard_ether. # script is called pccard_ether.
# #
# NB: DETACH events are ignored; the kernel should handle all cleanup # NB: DETACH events are ignored; the kernel should handle all cleanup
# (routes, arp cache) if you need to do something beware of races # (routes, arp cache). Beware of races against immediate create
# against immediate create of a device w/ the same name; e.g. # of a device with the same name; e.g.
# ifconfig bridge0 destroy; ifconfig bridge0 create # ifconfig bridge0 destroy; ifconfig bridge0 create
# #
notify 0 { 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 # up. Only devices that are configured to support DHCP will actually
# run it. No link down rule exists because dhclient automatically exits # run it. No link down rule exists because dhclient automatically exits
# when the link goes down. # when the link goes down.
@ -87,7 +87,7 @@ detach 100 {
device-name "ed50"; device-name "ed50";
}; };
# When a USB Bluetooth dongle appears activate it # When a USB Bluetooth dongle appears, activate it
attach 100 { attach 100 {
device-name "ubt[0-9]+"; device-name "ubt[0-9]+";
action "/etc/rc.d/bluetooth quietstart $device-name"; 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 # 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. # automatically.
attach 100 { attach 100 {
match "vendor" "0x0854"; match "vendor" "0x0854";
@ -265,12 +265,11 @@ notify 10 {
/* EXAMPLES TO END OF FILE /* EXAMPLES TO END OF FILE
# The following might be an example of something that a vendor might # An example of something that a vendor might install if you were to
# install if you were to add their device. This might reside in # add their device. This might reside in /usr/local/etc/devd/deqna.conf.
# /usr/local/etc/devd/deqna.conf. A deqna is, in this hypothetical # A deqna is, in this hypothetical example, a pccard ethernet-like device.
# example, a pccard ethernet-like device. Students of history may # Students of history may know other devices by this name, and will get
# know other devices by this name, and will get the in-jokes in this # the in-jokes in this entry.
# entry.
nomatch 10 { nomatch 10 {
match "bus" "pccard[0-9]+"; match "bus" "pccard[0-9]+";
match "manufacturer" "0x1234"; match "manufacturer" "0x1234";
@ -288,7 +287,7 @@ detach 10 {
# Examples of notify hooks. A notify is a generic way for a kernel # Examples of notify hooks. A notify is a generic way for a kernel
# subsystem to send event notification to userland. # subsystem to send event notification to userland.
#
# Here are some examples of ACPI notify handlers. ACPI subsystems that # Here are some examples of ACPI notify handlers. ACPI subsystems that
# generate notifies include the AC adapter, power/sleep buttons, # generate notifies include the AC adapter, power/sleep buttons,
# control method batteries, lid switch, and thermal zones. # control method batteries, lid switch, and thermal zones.
@ -316,7 +315,7 @@ notify 10 {
}; };
# This example works around a memory leak in PostgreSQL, restarting # 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 { notify 0 {
match "system" "RCTL"; match "system" "RCTL";
match "rule" "user:70:swap:.*"; match "rule" "user:70:swap:.*";

View File

@ -297,6 +297,10 @@ dhcpif()
local _tmpargs _arg local _tmpargs _arg
_tmpargs=`_ifconfig_getargs $1` _tmpargs=`_ifconfig_getargs $1`
if noafif $1; then
return 1
fi
for _arg in $_tmpargs; do for _arg in $_tmpargs; do
case $_arg in case $_arg in
[Dd][Hh][Cc][Pp]) [Dd][Hh][Cc][Pp])
@ -322,6 +326,10 @@ syncdhcpif()
local _tmpargs _arg local _tmpargs _arg
_tmpargs=`_ifconfig_getargs $1` _tmpargs=`_ifconfig_getargs $1`
if noafif $1; then
return 1
fi
for _arg in $_tmpargs; do for _arg in $_tmpargs; do
case $_arg in case $_arg in
[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/stat.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 */ /* Finally just format it */
snprintf(buf, len, "#%c:%d:0x%x", snprintf(buf, len, "#%c:%#jx",
S_ISCHR(type) ? 'C' : 'B', major(dev), minor(dev)); S_ISCHR(type) ? 'C' : 'B', (uintmax_t)dev);
return (buf); return (buf);
} }

View File

@ -32,7 +32,10 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h> #include <sys/param.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <dev/usb/usb_ioctl.h>
#include "usbhid.h" #include "usbhid.h"
#include "usbvar.h"
int32_t int32_t
hid_get_data(const void *p, const hid_item_t *h) 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))) | buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) |
((data >> (i*8)) & 0xff); ((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 MAXUSAGE 100
#define MAXPUSH 4 #define MAXPUSH 4
#define MAXID 64 #define MAXID 64
#define ITEMTYPES 3
struct hid_pos_data { struct hid_pos_data {
int32_t rid; int32_t rid;
uint32_t pos; uint32_t pos[ITEMTYPES];
}; };
struct hid_data { struct hid_data {
@ -55,6 +56,7 @@ struct hid_data {
const uint8_t *p; const uint8_t *p;
struct hid_item cur[MAXPUSH]; struct hid_item cur[MAXPUSH];
struct hid_pos_data last_pos[MAXID]; struct hid_pos_data last_pos[MAXID];
uint32_t pos[ITEMTYPES];
int32_t usages_min[MAXUSAGE]; int32_t usages_min[MAXUSAGE];
int32_t usages_max[MAXUSAGE]; int32_t usages_max[MAXUSAGE];
int32_t usage_last; /* last seen usage */ int32_t usage_last; /* last seen usage */
@ -92,7 +94,7 @@ hid_clear_local(hid_item_t *c)
static void static void
hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID) 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 */ /* 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) { if (i != MAXID) {
s->last_pos[i].rid = c->report_ID; 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 */ /* 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) { if (i != MAXID) {
s->last_pos[i].rid = next_rID; s->last_pos[i].rid = next_rID;
c->pos = s->last_pos[i].pos; for (j = 0; j < ITEMTYPES; j++)
} else s->pos[j] = s->last_pos[i].pos[j];
c->pos = 0; /* Out of RID entries. */ } 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; hid_item_t *c;
unsigned int bTag, bType, bSize; unsigned int bTag, bType, bSize;
uint32_t oldpos;
int32_t mask; int32_t mask;
int32_t dval; int32_t dval;
@ -240,7 +245,8 @@ hid_get_item(hid_data_t s, hid_item_t *h)
*/ */
if (s->kindset & (1 << c->kind)) { if (s->kindset & (1 << c->kind)) {
*h = *c; *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); return (1);
} }
} }
@ -406,14 +412,10 @@ hid_get_item(hid_data_t s, hid_item_t *h)
case 11: /* Pop */ case 11: /* Pop */
s->pushlevel --; s->pushlevel --;
if (s->pushlevel < MAXPUSH) { if (s->pushlevel < MAXPUSH) {
/* preserve position */
oldpos = c->pos;
c = &s->cur[s->pushlevel]; c = &s->cur[s->pushlevel];
/* restore size and count */ /* restore size and count */
s->loc_size = c->report_size; s->loc_size = c->report_size;
s->loc_count = c->report_count; s->loc_count = c->report_count;
/* set default item location */
c->pos = oldpos;
c->report_size = 0; c->report_size = 0;
c->report_count = 0; c->report_count = 0;
} }

View File

@ -44,7 +44,9 @@
.Nm hid_usage_in_page , .Nm hid_usage_in_page ,
.Nm hid_init , .Nm hid_init ,
.Nm hid_get_data , .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 .Nd USB HID access routines
.Sh LIBRARY .Sh LIBRARY
.Lb libusbhid .Lb libusbhid
@ -84,6 +86,10 @@
.Fn hid_get_data "const void *data" "const hid_item_t *h" .Fn hid_get_data "const void *data" "const hid_item_t *h"
.Ft void .Ft void
.Fn hid_set_data "void *buf" "const hid_item_t *h" "int data" .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 .Sh DESCRIPTION
The The
.Nm .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. If the second argument is zero synchronous HID operation is disabled.
Else synchronous HID operation is enabled. Else synchronous HID operation is enabled.
The function returns a negative value on failure. 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 .Ss Descriptor Functions
The report descriptor ID can be obtained by calling The report descriptor ID can be obtained by calling
.Fn hid_get_report_id . .Fn hid_get_report_id .

View File

@ -76,6 +76,7 @@ typedef struct hid_item {
#define HID_PAGE(u) (((u) >> 16) & 0xffff) #define HID_PAGE(u) (((u) >> 16) & 0xffff)
#define HID_USAGE(u) ((u) & 0xffff) #define HID_USAGE(u) ((u) & 0xffff)
#define HID_HAS_GET_SET_REPORT 1
__BEGIN_DECLS __BEGIN_DECLS
@ -104,5 +105,9 @@ int hid_parse_usage_page(const char *name);
/* Extracting/insertion of data, data.c: */ /* Extracting/insertion of data, data.c: */
int32_t hid_get_data(const void *p, const hid_item_t *h); 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); 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 __END_DECLS

View File

@ -126,12 +126,10 @@ printstat(const char *cp, ino_t inum, union dinode *dp)
puts("regular file"); puts("regular file");
break; break;
case IFBLK: case IFBLK:
printf("block special (%d,%d)", printf("block special (%#jx)", (uintmax_t)DIP(dp, di_rdev));
major(DIP(dp, di_rdev)), minor(DIP(dp, di_rdev)));
break; break;
case IFCHR: case IFCHR:
printf("character special (%d,%d)", printf("character special (%#jx)", DIP(dp, di_rdev));
major(DIP(dp, di_rdev)), minor(DIP(dp, di_rdev)));
break; break;
case IFLNK: case IFLNK:
fputs("symlink",stdout); fputs("symlink",stdout);

View File

@ -63,6 +63,7 @@ checksum <algorithm>
compression <algorithm> compression <algorithm>
timeout <seconds> timeout <seconds>
exec <path> exec <path>
metaflush "on" | "off"
on <node> { on <node> {
# Node section # Node section
@ -85,12 +86,14 @@ resource <name> {
local <path> local <path>
timeout <seconds> timeout <seconds>
exec <path> exec <path>
metaflush "on" | "off"
on <node> { on <node> {
# Resource-node section # Resource-node section
name <name> name <name>
# Required # Required
local <path> local <path>
metaflush "on" | "off"
# Required # Required
remote <addr> remote <addr>
source <addr> source <addr>
@ -100,6 +103,7 @@ resource <name> {
name <name> name <name>
# Required # Required
local <path> local <path>
metaflush "on" | "off"
# Required # Required
remote <addr> remote <addr>
source <addr> source <addr>
@ -318,6 +322,25 @@ It can be one of:
.Ar secondary , .Ar secondary ,
.Ar primary . .Ar primary .
.Pp .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 .It Ic name Aq name
.Pp .Pp
GEOM provider name that will appear as GEOM provider name that will appear as

View File

@ -167,6 +167,10 @@ struct hast_resource {
off_t hr_local_mediasize; off_t hr_local_mediasize;
/* Sector size of local provider. */ /* Sector size of local provider. */
unsigned int hr_local_sectorsize; 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. */ /* Descriptor for /dev/ggctl communication. */
int hr_ggatefd; int hr_ggatefd;

View File

@ -386,6 +386,12 @@ resource_needs_restart(const struct hast_resource *res0,
return (true); return (true);
if (strcmp(res0->hr_exec, res1->hr_exec) != 0) if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
return (true); 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); return (false);
} }
@ -416,6 +422,8 @@ resource_needs_reload(const struct hast_resource *res0,
return (true); return (true);
if (strcmp(res0->hr_exec, res1->hr_exec) != 0) if (strcmp(res0->hr_exec, res1->hr_exec) != 0)
return (true); return (true);
if (res0->hr_metaflush != res1->hr_metaflush)
return (true);
return (false); 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_compression, "compression");
nv_add_int32(nvout, (int32_t)res->hr_timeout, "timeout"); nv_add_int32(nvout, (int32_t)res->hr_timeout, "timeout");
nv_add_string(nvout, res->hr_exec, "exec"); nv_add_string(nvout, res->hr_exec, "exec");
nv_add_int32(nvout, (int32_t)res->hr_metaflush, "metaflush");
if (nv_error(nvout) != 0) { if (nv_error(nvout) != 0) {
nv_free(nvout); nv_free(nvout);
pjdlog_error("Unable to allocate header for reload message."); pjdlog_error("Unable to allocate header for reload message.");
@ -591,12 +600,13 @@ hastd_reload(void)
* recreating it. * recreating it.
* *
* We do just reload (send SIGHUP to worker process) if we act as * We do just reload (send SIGHUP to worker process) if we act as
* PRIMARY, but only if remote address, replication mode, timeout or * PRIMARY, but only if remote address, source address, replication
* execution path has changed. For those, there is no need to restart * mode, timeout, execution path or metaflush has changed.
* worker process. * For those, there is no need to restart worker process.
* If PRIMARY receives SIGHUP, it will reconnect if remote address or * If PRIMARY receives SIGHUP, it will reconnect if remote address or
* replication mode has changed or simply set new timeout if only * source address has changed or it will set new timeout if only timeout
* timeout has changed. * has changed or it will update metaflush if only metaflush has
* changed.
*/ */
TAILQ_FOREACH_SAFE(nres, &newcfg->hc_resources, hr_next, tres) { TAILQ_FOREACH_SAFE(nres, &newcfg->hc_resources, hr_next, tres) {
TAILQ_FOREACH(cres, &cfg->hc_resources, hr_next) { TAILQ_FOREACH(cres, &cfg->hc_resources, hr_next) {
@ -627,6 +637,7 @@ hastd_reload(void)
cres->hr_timeout = nres->hr_timeout; cres->hr_timeout = nres->hr_timeout;
strlcpy(cres->hr_exec, nres->hr_exec, strlcpy(cres->hr_exec, nres->hr_exec,
sizeof(cres->hr_exec)); sizeof(cres->hr_exec));
cres->hr_metaflush = nres->hr_metaflush;
if (cres->hr_workerpid != 0) if (cres->hr_workerpid != 0)
resource_reload(cres); resource_reload(cres);
} }

View File

@ -68,9 +68,11 @@ static int depth0_checksum;
static int depth0_compression; static int depth0_compression;
static int depth0_timeout; static int depth0_timeout;
static char depth0_exec[PATH_MAX]; static char depth0_exec[PATH_MAX];
static int depth0_metaflush;
static char depth1_provname[PATH_MAX]; static char depth1_provname[PATH_MAX];
static char depth1_localpath[PATH_MAX]; static char depth1_localpath[PATH_MAX];
static int depth1_metaflush;
extern void yyrestart(FILE *); extern void yyrestart(FILE *);
@ -197,6 +199,7 @@ yy_config_parse(const char *config, bool exitonerror)
strlcpy(depth0_listen_tcp6, HASTD_LISTEN_TCP6, strlcpy(depth0_listen_tcp6, HASTD_LISTEN_TCP6,
sizeof(depth0_listen_tcp6)); sizeof(depth0_listen_tcp6));
depth0_exec[0] = '\0'; depth0_exec[0] = '\0';
depth0_metaflush = 1;
lconfig = calloc(1, sizeof(*lconfig)); lconfig = calloc(1, sizeof(*lconfig));
if (lconfig == NULL) { if (lconfig == NULL) {
@ -328,6 +331,13 @@ yy_config_parse(const char *config, bool exitonerror)
strlcpy(curres->hr_exec, depth0_exec, strlcpy(curres->hr_exec, depth0_exec,
sizeof(curres->hr_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); return (lconfig);
@ -355,8 +365,8 @@ yy_config_free(struct hastd_config *config)
} }
%} %}
%token CONTROL LISTEN PORT REPLICATION CHECKSUM COMPRESSION %token CONTROL LISTEN PORT REPLICATION CHECKSUM COMPRESSION METAFLUSH
%token TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE SOURCE ON %token TIMEOUT EXEC EXTENTSIZE RESOURCE NAME LOCAL REMOTE SOURCE ON OFF
%token FULLSYNC MEMSYNC ASYNC NONE CRC32 SHA256 HOLE LZF %token FULLSYNC MEMSYNC ASYNC NONE CRC32 SHA256 HOLE LZF
%token NUM STR OB CB %token NUM STR OB CB
@ -364,6 +374,7 @@ yy_config_free(struct hastd_config *config)
%type <num> replication_type %type <num> replication_type
%type <num> checksum_type %type <num> checksum_type
%type <num> compression_type %type <num> compression_type
%type <num> boolean
%union %union
{ {
@ -396,6 +407,8 @@ statement:
| |
exec_statement exec_statement
| |
metaflush_statement
|
node_statement node_statement
| |
resource_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 node_statement: ON node_start OB node_entries CB
{ {
mynode = false; mynode = false;
@ -660,6 +701,13 @@ resource_statement: RESOURCE resource_start OB resource_entries CB
strlcpy(curres->hr_localpath, depth1_localpath, strlcpy(curres->hr_localpath, depth1_localpath,
sizeof(curres->hr_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 * If provider name is not given, use resource name
@ -713,6 +761,7 @@ resource_start: STR
*/ */
depth1_provname[0] = '\0'; depth1_provname[0] = '\0';
depth1_localpath[0] = '\0'; depth1_localpath[0] = '\0';
depth1_metaflush = -1;
hadmynode = false; hadmynode = false;
curres = calloc(1, sizeof(*curres)); curres = calloc(1, sizeof(*curres));
@ -739,6 +788,8 @@ resource_start: STR
curres->hr_provname[0] = '\0'; curres->hr_provname[0] = '\0';
curres->hr_localpath[0] = '\0'; curres->hr_localpath[0] = '\0';
curres->hr_localfd = -1; curres->hr_localfd = -1;
curres->hr_localflush = true;
curres->hr_metaflush = -1;
curres->hr_remoteaddr[0] = '\0'; curres->hr_remoteaddr[0] = '\0';
curres->hr_sourceaddr[0] = '\0'; curres->hr_sourceaddr[0] = '\0';
curres->hr_ggateunit = -1; curres->hr_ggateunit = -1;
@ -761,6 +812,8 @@ resource_entry:
| |
exec_statement exec_statement
| |
metaflush_statement
|
name_statement name_statement
| |
local_statement local_statement
@ -869,6 +922,8 @@ resource_node_entry:
remote_statement remote_statement
| |
source_statement source_statement
|
metaflush_statement
; ;
remote_statement: REMOTE remote_str 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"); pjdlog_errno(LOG_ERR, "Unable to flush activemap to disk");
return (-1); 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); return (0);
} }
@ -1202,7 +1213,7 @@ ggate_recv_thread(void *arg)
break; break;
} }
pjdlog_debug(2, pjdlog_debug(2,
"ggate_recv: (%p) Moving request to the send queues.", "ggate_recv: (%p) Moving request to the send queue.",
hio); hio);
refcount_init(&hio->hio_countdown, ncomps); refcount_init(&hio->hio_countdown, ncomps);
for (ii = 0; ii < ncomps; ii++) for (ii = 0; ii < ncomps; ii++)
@ -1293,8 +1304,15 @@ local_send_thread(void *arg)
} }
break; break;
case BIO_FLUSH: case BIO_FLUSH:
if (!res->hr_localflush) {
ret = -1;
errno = EOPNOTSUPP;
break;
}
ret = g_flush(res->hr_localfd); ret = g_flush(res->hr_localfd);
if (ret < 0) { if (ret < 0) {
if (errno == EOPNOTSUPP)
res->hr_localflush = false;
hio->hio_errors[ncomp] = errno; hio->hio_errors[ncomp] = errno;
reqlog(LOG_WARNING, 0, ggio, reqlog(LOG_WARNING, 0, ggio,
"Local request failed (%s): ", "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, "compression");
nv_assert(nv, "timeout"); nv_assert(nv, "timeout");
nv_assert(nv, "exec"); nv_assert(nv, "exec");
nv_assert(nv, "metaflush");
ncomps = HAST_NCOMPONENTS; ncomps = HAST_NCOMPONENTS;
@ -2009,6 +2028,7 @@ primary_config_reload(struct hast_resource *res, struct nv *nv)
#define MODIFIED_COMPRESSION 0x10 #define MODIFIED_COMPRESSION 0x10
#define MODIFIED_TIMEOUT 0x20 #define MODIFIED_TIMEOUT 0x20
#define MODIFIED_EXEC 0x40 #define MODIFIED_EXEC 0x40
#define MODIFIED_METAFLUSH 0x80
modified = 0; modified = 0;
vstr = nv_get_string(nv, "remoteaddr"); 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)); strlcpy(gres->hr_exec, vstr, sizeof(gres->hr_exec));
modified |= MODIFIED_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. * Change timeout for connected sockets.
@ -2099,6 +2124,7 @@ primary_config_reload(struct hast_resource *res, struct nv *nv)
#undef MODIFIED_COMPRESSION #undef MODIFIED_COMPRESSION
#undef MODIFIED_TIMEOUT #undef MODIFIED_TIMEOUT
#undef MODIFIED_EXEC #undef MODIFIED_EXEC
#undef MODIFIED_METAFLUSH
pjdlog_info("Configuration reloaded successfully."); pjdlog_info("Configuration reloaded successfully.");
} }

View File

@ -664,7 +664,7 @@ disk_thread(void *arg)
struct hast_resource *res = arg; struct hast_resource *res = arg;
struct hio *hio; struct hio *hio;
ssize_t ret; ssize_t ret;
bool clear_activemap; bool clear_activemap, logerror;
clear_activemap = true; clear_activemap = true;
@ -699,8 +699,10 @@ disk_thread(void *arg)
free(map); free(map);
clear_activemap = false; clear_activemap = false;
pjdlog_debug(1, "Local activemap cleared."); pjdlog_debug(1, "Local activemap cleared.");
break;
} }
reqlog(LOG_DEBUG, 2, -1, hio, "disk: (%p) Got request: ", hio); reqlog(LOG_DEBUG, 2, -1, hio, "disk: (%p) Got request: ", hio);
logerror = true;
/* Handle the actual request. */ /* Handle the actual request. */
switch (hio->hio_cmd) { switch (hio->hio_cmd) {
case HIO_READ: case HIO_READ:
@ -735,14 +737,23 @@ disk_thread(void *arg)
hio->hio_error = 0; hio->hio_error = 0;
break; break;
case HIO_FLUSH: case HIO_FLUSH:
if (!res->hr_localflush) {
ret = -1;
hio->hio_error = EOPNOTSUPP;
logerror = false;
break;
}
ret = g_flush(res->hr_localfd); ret = g_flush(res->hr_localfd);
if (ret < 0) if (ret < 0) {
if (errno == EOPNOTSUPP)
res->hr_localflush = false;
hio->hio_error = errno; hio->hio_error = errno;
else } else {
hio->hio_error = 0; hio->hio_error = 0;
}
break; break;
} }
if (hio->hio_error != 0) { if (logerror && hio->hio_error != 0) {
reqlog(LOG_ERR, 0, hio->hio_error, hio, reqlog(LOG_ERR, 0, hio->hio_error, hio,
"Request failed: "); "Request failed: ");
} }

View File

@ -53,12 +53,14 @@ checksum { DP; return CHECKSUM; }
compression { DP; return COMPRESSION; } compression { DP; return COMPRESSION; }
timeout { DP; return TIMEOUT; } timeout { DP; return TIMEOUT; }
exec { DP; return EXEC; } exec { DP; return EXEC; }
metaflush { DP; return METAFLUSH; }
resource { DP; return RESOURCE; } resource { DP; return RESOURCE; }
name { DP; return NAME; } name { DP; return NAME; }
local { DP; return LOCAL; } local { DP; return LOCAL; }
remote { DP; return REMOTE; } remote { DP; return REMOTE; }
source { DP; return SOURCE; } source { DP; return SOURCE; }
on { DP; return ON; } on { DP; return ON; }
off { DP; return OFF; }
fullsync { DP; return FULLSYNC; } fullsync { DP; return FULLSYNC; }
memsync { DP; return MEMSYNC; } memsync { DP; return MEMSYNC; }
async { DP; return ASYNC; } async { DP; return ASYNC; }

View File

@ -238,7 +238,7 @@ This command takes a long time.
Get updated sources as configured in Get updated sources as configured in
.Xr make.conf 5 . .Xr make.conf 5 .
.It Cm targets .It Cm targets
Print a list of supported Print a list of supported
.Va TARGET .Va TARGET
/ /
.Va TARGET_ARCH .Va TARGET_ARCH
@ -399,21 +399,31 @@ It defaults to
.It Va KERNFAST .It Va KERNFAST
If set, the build target If set, the build target
.Cm buildkernel .Cm buildkernel
defaults to setting defaults to setting
.Va NO_KERNELCLEAN , .Va NO_KERNELCLEAN ,
.Va NO_KERNELCONFIG , .Va NO_KERNELCONFIG ,
.Va NO_KERNELDEPEND .Va NO_KERNELDEPEND
and and
.Va NO_KERNELOBJ . .Va NO_KERNELOBJ .
When set to a value other than When set to a value other than
.Cm 1 .Cm 1
then then
.Va KERNCONF .Va KERNCONF
is set to the value of is set to the value of
.Va KERNFAST . .Va KERNFAST .
.It Va LOCAL_DIRS .It Va LOCAL_DIRS
If set, this variable supplies a list of additional directories to If set, this variable supplies a list of additional directories to
build, relative to the root of the source tree. 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 .It Va SUBDIR_OVERRIDE
Override the default list of sub-directories and only build the Override the default list of sub-directories and only build the
sub-directory named in this variable. sub-directory named in this variable.
@ -442,11 +452,11 @@ output.
Set this to cross-build for a different architecture. Set this to cross-build for a different architecture.
If not set, If not set,
.Va TARGET_ARCH .Va TARGET_ARCH
defaults to the current machine architecture, unless defaults to the current machine architecture, unless
.Va TARGET .Va TARGET
is also set, in which case it defaults to the appropriate is also set, in which case it defaults to the appropriate
value for that platform. value for that platform.
Typically, one only needs to set Typically, one only needs to set
.Va TARGET . .Va TARGET .
.El .El
.Pp .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"] demon [label="Dmitry Sivachenko\ndemon@FreeBSD.org\n2000/11/13"]
dhn [label="Dennis Herrmann\ndhn@FreeBSD.org\n2009/03/03"] dhn [label="Dennis Herrmann\ndhn@FreeBSD.org\n2009/03/03"]
dryice [label="Dryice Dong Liu\ndryice@FreeBSD.org\n2006/12/25"] 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"] edwin [label="Edwin Groothuis\nedwin@FreeBSD.org\n2002/10/22"]
ehaupt [label="Emanuel Haupt\nehaupt@FreeBSD.org\n2005/10/03"] ehaupt [label="Emanuel Haupt\nehaupt@FreeBSD.org\n2005/10/03"]
eik [label="Oliver Eikemeier\neik@FreeBSD.org\n2003/11/12"] eik [label="Oliver Eikemeier\neik@FreeBSD.org\n2003/11/12"]
@ -209,6 +210,7 @@ arved -> stefan
asami -> obrien asami -> obrien
bapt -> eadler
bapt -> jlaffaye bapt -> jlaffaye
beat -> decke beat -> decke
@ -385,6 +387,7 @@ rafan -> chinsan
rene -> crees rene -> crees
sahil -> culot sahil -> culot
sahil -> eadler
sat -> beech 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; struct mfi_command *cm;
union mfi_sgl *sgl; union mfi_sgl *sgl;
struct mfi_softc *sc; struct mfi_softc *sc;
int i, dir; int i, j, first, dir;
cm = (struct mfi_command *)arg; cm = (struct mfi_command *)arg;
sc = cm->cm_sc; sc = cm->cm_sc;
@ -1502,19 +1502,33 @@ mfi_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
return; 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) { if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
for (i = 0; i < nsegs; i++) { for (i = 0; i < nsegs; i++) {
sgl->sg32[i].addr = segs[i].ds_addr; sgl->sg32[j].addr = segs[i].ds_addr + first;
sgl->sg32[i].len = segs[i].ds_len; sgl->sg32[j++].len = segs[i].ds_len - first;
first = 0;
} }
} else { } else {
for (i = 0; i < nsegs; i++) { for (i = 0; i < nsegs; i++) {
sgl->sg64[i].addr = segs[i].ds_addr; sgl->sg64[j].addr = segs[i].ds_addr + first;
sgl->sg64[i].len = segs[i].ds_len; sgl->sg64[j++].len = segs[i].ds_len - first;
first = 0;
} }
hdr->flags |= MFI_FRAME_SGL64; hdr->flags |= MFI_FRAME_SGL64;
} }
hdr->sg_count = nsegs; hdr->sg_count = j;
dir = 0; dir = 0;
if (cm->cm_flags & MFI_CMD_DATAIN) { 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; dir |= BUS_DMASYNC_PREWRITE;
hdr->flags |= MFI_FRAME_DIR_WRITE; 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); bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
cm->cm_flags |= MFI_CMD_MAPPED; 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) { if ((cm->cm_flags & MFI_CMD_MAPPED) != 0) {
dir = 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; dir |= BUS_DMASYNC_POSTREAD;
if (cm->cm_flags & MFI_CMD_DATAOUT) if (cm->cm_flags & MFI_CMD_DATAOUT)
dir |= BUS_DMASYNC_POSTWRITE; 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; struct mfi_command *cm = NULL;
uint32_t context; uint32_t context;
union mfi_sense_ptr sense_ptr; union mfi_sense_ptr sense_ptr;
uint8_t *data = NULL, *temp; uint8_t *data = NULL, *temp, *addr;
size_t len;
int i; int i;
struct mfi_ioc_passthru *iop = (struct mfi_ioc_passthru *)arg; struct mfi_ioc_passthru *iop = (struct mfi_ioc_passthru *)arg;
#ifdef __amd64__ #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) if (cm->cm_flags == 0)
cm->cm_flags |= MFI_CMD_DATAIN | MFI_CMD_DATAOUT; cm->cm_flags |= MFI_CMD_DATAIN | MFI_CMD_DATAOUT;
cm->cm_len = cm->cm_frame->header.data_len; 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 && if (cm->cm_len &&
(cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) { (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) {
cm->cm_data = data = malloc(cm->cm_len, M_MFIBUF, 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; cm->cm_frame->header.context = context;
temp = data; 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++) { for (i = 0; i < ioc->mfi_sge_count; i++) {
#ifdef __amd64__ #ifdef __amd64__
if (cmd == MFI_CMD) { 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 #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) { if (error != 0) {
device_printf(sc->mfi_dev, device_printf(sc->mfi_dev,
"Copy in failed\n"); "Copy in failed\n");
goto out; 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); mtx_unlock(&sc->mfi_io_lock);
temp = data; 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++) { for (i = 0; i < ioc->mfi_sge_count; i++) {
#ifdef __amd64__ #ifdef __amd64__
if (cmd == MFI_CMD) { 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 #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) { if (error != 0) {
device_printf(sc->mfi_dev, device_printf(sc->mfi_dev,
"Copy out failed\n"); "Copy out failed\n");
goto out; 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; union mfi_sgl *cm_sg;
void *cm_data; void *cm_data;
int cm_len; int cm_len;
int cm_stp_len;
int cm_total_frame_size; int cm_total_frame_size;
int cm_extra_frames; int cm_extra_frames;
int cm_flags; int cm_flags;

View File

@ -566,8 +566,10 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr,
default: default:
return (EINVAL); return (EINVAL);
} }
if (id != 0)
copyin(ugd->ugd_data, &id, 1);
error = uhid_get_report(sc, ugd->ugd_report_type, id, 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; break;
case USB_SET_REPORT: case USB_SET_REPORT:
@ -592,8 +594,10 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr,
default: default:
return (EINVAL); return (EINVAL);
} }
if (id != 0)
copyin(ugd->ugd_data, &id, 1);
error = uhid_set_report(sc, ugd->ugd_report_type, id, 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; break;
case USB_GET_REPORT_ID: 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 * Library routines for raw socket usrreq functions; will always be wrapped
* so that protocol-specific functions can be handled. * 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); int raw_attach(struct socket *, int);
void raw_detach(struct rawcb *); void raw_detach(struct rawcb *);
void raw_input(struct mbuf *, struct sockproto *, struct sockaddr *); 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 * Generic pr_usrreqs entries for raw socket protocols, usually wrapped so

View File

@ -70,6 +70,14 @@ raw_init(void)
*/ */
void void
raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src) 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 rawcb *rp;
struct mbuf *m = m0; 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 && if (rp->rcb_proto.sp_protocol &&
rp->rcb_proto.sp_protocol != proto->sp_protocol) rp->rcb_proto.sp_protocol != proto->sp_protocol)
continue; continue;
if (cb != NULL && (*cb)(m, proto, src, rp) != 0)
continue;
if (last) { if (last) {
struct mbuf *n; struct mbuf *n;
n = m_copy(m, 0, (int)M_COPYALL); n = m_copy(m, 0, (int)M_COPYALL);

View File

@ -384,7 +384,7 @@ miss:
*/ */
bzero(&info, sizeof(info)); bzero(&info, sizeof(info));
info.rti_info[RTAX_DST] = dst; info.rti_info[RTAX_DST] = dst;
rt_missmsg(msgtype, &info, 0, err); rt_missmsg_fib(msgtype, &info, 0, err, fibnum);
} }
done: done:
if (newrt) if (newrt)
@ -609,7 +609,7 @@ out:
info.rti_info[RTAX_GATEWAY] = gateway; info.rti_info[RTAX_GATEWAY] = gateway;
info.rti_info[RTAX_NETMASK] = netmask; info.rti_info[RTAX_NETMASK] = netmask;
info.rti_info[RTAX_AUTHOR] = src; 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) if (ifa != NULL)
ifa_free(ifa); ifa_free(ifa);
} }
@ -1522,7 +1522,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
} }
RT_ADDREF(rt); RT_ADDREF(rt);
RT_UNLOCK(rt); RT_UNLOCK(rt);
rt_newaddrmsg(cmd, ifa, error, rt); rt_newaddrmsg_fib(cmd, ifa, error, rt, fibnum);
RT_LOCK(rt); RT_LOCK(rt);
RT_REMREF(rt); RT_REMREF(rt);
if (cmd == RTM_DELETE) { 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_ifannouncemsg(struct ifnet *, int);
void rt_ifmsg(struct ifnet *); void rt_ifmsg(struct ifnet *);
void rt_missmsg(int, struct rt_addrinfo *, int, int); 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(int, struct ifaddr *, int, struct rtentry *);
void rt_newaddrmsg_fib(int, struct ifaddr *, int, struct rtentry *, int);
void rt_newmaddrmsg(int, struct ifmultiaddr *); void rt_newmaddrmsg(int, struct ifmultiaddr *);
int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *); int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
void rt_maskedcopy(struct sockaddr *, 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 route_src = { 2, PF_ROUTE, };
static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, }; 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 { static struct {
int ip_count; /* attached w/ AF_INET */ int ip_count; /* attached w/ AF_INET */
int ip6_count; /* attached w/ AF_INET6 */ 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); 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 static void
rts_input(struct mbuf *m) rts_input(struct mbuf *m)
{ {
@ -212,7 +244,7 @@ rts_input(struct mbuf *m)
} else } else
route_proto.sp_protocol = 0; 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); m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
} }
if (m) { if (m) {
M_SETFIB(m, so->so_fibnum);
m->m_flags |= RTS_FILTER_FIB;
if (rp) { if (rp) {
/* /*
* XXX insure we don't get a copy by * XXX insure we don't get a copy by
@ -1127,7 +1161,8 @@ again:
* destination. * destination.
*/ */
void 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 rt_msghdr *rtm;
struct mbuf *m; struct mbuf *m;
@ -1138,6 +1173,14 @@ rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
m = rt_msg1(type, rtinfo); m = rt_msg1(type, rtinfo);
if (m == NULL) if (m == NULL)
return; 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 = mtod(m, struct rt_msghdr *);
rtm->rtm_flags = RTF_DONE | flags; rtm->rtm_flags = RTF_DONE | flags;
rtm->rtm_errno = error; rtm->rtm_errno = error;
@ -1145,6 +1188,13 @@ rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
rt_dispatch(m, sa); 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 * This routine is called to generate a message from the routing
* socket indicating that the status of a network interface has changed. * socket indicating that the status of a network interface has changed.
@ -1179,7 +1229,8 @@ rt_ifmsg(struct ifnet *ifp)
* copies of it. * copies of it.
*/ */
void 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 rt_addrinfo info;
struct sockaddr *sa = NULL; 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_errno = error;
rtm->rtm_addrs = info.rti_addrs; 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); 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 * This is the analogue to the rt_newaddrmsg which performs the same
* function but for multicast group memberhips. This is easier since * 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 * If the object is locked and the page is neither VPO_BUSY nor
* PGA_WRITEABLE, then the page's dirty field cannot possibly be * PGA_WRITEABLE, then the page's dirty field cannot possibly be
* set by a concurrent pmap operation. * set by a concurrent pmap operation.
*
*/ */
VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) 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 * For PAGE_SIZE == 32768 case, compiler already
* properly aligns the dirty field, so no forcible * properly aligns the dirty field, so no forcible
* alignment is needed. Only require existence of * 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; addr = (uintptr_t)&m->dirty;
#if PAGE_SIZE == 32768 #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); atomic_clear_32((uint32_t *)addr, pagebits);
#else /* PAGE_SIZE <= 8192 */ #else /* PAGE_SIZE <= 8192 */
/* /*
* Use a trick to perform an 32bit atomic on the * Use a trick to perform a 32-bit atomic on the
* contained aligned word, to not depend on existence * containing aligned word, to not depend on the existence
* of the atomic_clear_{8, 16}. * of atomic_clear_{8, 16}.
*/ */
shift = addr & (sizeof(uint32_t) - 1); shift = addr & (sizeof(uint32_t) - 1);
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN

View File

@ -105,7 +105,7 @@
* the field without holding that lock. If the underlying * the field without holding that lock. If the underlying
* architecture does not support atomic read-modify-write * architecture does not support atomic read-modify-write
* operations on the field's type, then the machine-independent * 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, * contains the dirty field. In the machine-independent layer,
* the implementation of read-modify-write operations on the * the implementation of read-modify-write operations on the
* field is encapsulated in vm_page_clear_dirty_mask(). * 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 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 Dmitry Chagin <dchagin@FreeBSD.org> born in Stalingrad, USSR, 1976
02/02 Yoichi Nakayama <yoichi@FreeBSD.org> born in Tsu, Mie, Japan, 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/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 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 02/10 Paul Richards <paul@FreeBSD.org> born in Ammanford, Carmarthenshire, United Kingdom, 1968

View File

@ -26,11 +26,10 @@
* $FreeBSD$ * $FreeBSD$
*/ */
#include <sys/limits.h>
#include <assert.h> #include <assert.h>
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -31,7 +31,7 @@
.\" @(#)find.1 8.7 (Berkeley) 5/9/95 .\" @(#)find.1 8.7 (Berkeley) 5/9/95
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 17, 2010 .Dd September 28, 2011
.Dt FIND 1 .Dt FIND 1
.Os .Os
.Sh NAME .Sh NAME
@ -507,7 +507,7 @@ This primary always evaluates to true.
The following information for the current file is written to standard output: 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 its inode number, size in 512-byte blocks, file permissions, number of hard
links, owner, group, size in bytes, last modification time, and pathname. 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. 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 If the file is a symbolic link, the pathname of the linked-to file will be
displayed preceded by displayed preceded by

View File

@ -70,8 +70,7 @@ printlong(char *name, char *accpath, struct stat *sb)
group_from_gid(sb->st_gid, 0)); group_from_gid(sb->st_gid, 0));
if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode)) if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode))
(void)printf("%3d, %3d ", major(sb->st_rdev), (void)printf("%#8jx ", (uintmax_t)sb->st_rdev);
minor(sb->st_rdev));
else else
(void)printf("%8"PRId64" ", sb->st_size); (void)printf("%8"PRId64" ", sb->st_size);
printtime(sb->st_mtime); printtime(sb->st_mtime);

View File

@ -28,7 +28,7 @@
.\" @(#)fstat.1 8.3 (Berkeley) 2/25/94 .\" @(#)fstat.1 8.3 (Berkeley) 2/25/94
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd July 9, 2009 .Dd September 28, 2011
.Dt FSTAT 1 .Dt FSTAT 1
.Os .Os
.Sh NAME .Sh NAME
@ -142,7 +142,7 @@ pathname that the file system the file resides in is mounted on.
If the If the
.Fl n .Fl n
flag is specified, this header is present and is the 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 .It Li INUM
The inode number of the file. The inode number of the file.
.It Li MODE .It Li MODE

View File

@ -411,7 +411,7 @@ print_pts_info(struct procstat *procstat, struct filestat *fst)
} }
printf("* pseudo-terminal master "); printf("* pseudo-terminal master ");
if (nflg || !*pts.devname) { if (nflg || !*pts.devname) {
printf("%10d,%-2d", major(pts.dev), minor(pts.dev)); printf("%#10jx", (uintmax_t)pts.dev);
} else { } else {
printf("%10s", pts.devname); printf("%10s", pts.devname);
} }
@ -441,7 +441,7 @@ print_vnode_info(struct procstat *procstat, struct filestat *fst)
} }
if (nflg) 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) else if (vn.vn_mntdir != NULL)
(void)printf(" %-8s", vn.vn_mntdir); (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 (vn.vn_type == PS_FST_VTYPE_VBLK || vn.vn_type == PS_FST_VTYPE_VCHR) {
if (nflg || !*vn.vn_devname) if (nflg || !*vn.vn_devname)
printf(" %2d,%-2d", major(vn.vn_dev), minor(vn.vn_dev)); printf(" %#6jx", (uintmax_t)vn.vn_dev);
else { else {
printf(" %6s", vn.vn_devname); 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 * Copyright (c) 1985, 1986, 1992, 1993

View File

@ -28,7 +28,7 @@
.\" @(#)script.1 8.1 (Berkeley) 6/6/93 .\" @(#)script.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd January 22, 2004 .Dd September 28, 2011
.Dt SCRIPT 1 .Dt SCRIPT 1
.Os .Os
.Sh NAME .Sh NAME
@ -73,15 +73,16 @@ or
.Pa typescript , .Pa typescript ,
retaining the prior contents. retaining the prior contents.
.It Fl k .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 .It Fl q
Run in quiet mode, omit the start and stop status messages. Run in quiet mode, omit the start and stop status messages.
.It Fl t Ar time .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 A value of 0
causes causes
.Nm .Nm
to flush for every character I/O event. to flush after every character I/O event.
The default interval is The default interval is
30 seconds. 30 seconds.
.El .El
@ -136,13 +137,15 @@ If
.Ev SHELL .Ev SHELL
is not set, the Bourne shell is not set, the Bourne shell
is assumed. is assumed.
(Most shells set this variable automatically). .Pq Most shells set this variable automatically .
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr csh 1 .Xr csh 1
(for the .Po
for the
.Em history .Em history
mechanism). mechanism
.Pc .
.Sh HISTORY .Sh HISTORY
The The
.Nm .Nm
@ -165,13 +168,15 @@ mode, echo cancelling is far from ideal.
The slave terminal mode is checked The slave terminal mode is checked
for ECHO mode to check when to avoid manual echo logging. for ECHO mode to check when to avoid manual echo logging.
This does not 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 .Pp
If the If
.Nm .Nm
reads zero bytes from the terminal it switches to a mode when it probes read reads zero bytes from the terminal, it switches to a mode when it
only once a second until it gets some data. only attempts to read
This prevents the once a second until there is data to read.
This prevents
.Nm .Nm
spinning on zero-byte reads, but might cause a 1-second delay in from spinning on zero-byte reads, but might cause a 1-second delay in
processing of the user input. processing of user input.

View File

@ -99,8 +99,7 @@ a debounce value, and an action.
There must be whitespace between the parts. There must be whitespace between the parts.
.Pp .Pp
The item names are similar to those used by The item names are similar to those used by
.Xr usbhidctl 1 , .Xr usbhidctl 1 .
but each part must be prefixed by its page name.
.Pp .Pp
The value is simply a numeric value. The value is simply a numeric value.
When the item reports this 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; char *p;
int line; int line;
char buf[SIZE], name[SIZE], value[SIZE], debounce[SIZE], action[SIZE]; 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 command *cmd, *cmds;
struct hid_data *d; struct hid_data *d;
struct hid_item h; struct hid_item h;
int u, lo, hi, range; int inst, cinst, u, lo, hi, range, t;
f = fopen(conf, "r"); f = fopen(conf, "r");
if (f == NULL) 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); ", 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); cmd = malloc(sizeof *cmd);
if (cmd == NULL) if (cmd == NULL)
@ -361,6 +366,7 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore)
} }
coll[0] = 0; coll[0] = 0;
cinst = 0;
for (d = hid_start_parse(repd, 1 << hid_input, reportid); for (d = hid_start_parse(repd, 1 << hid_input, reportid);
hid_get_item(d, &h); ) { hid_get_item(d, &h); ) {
if (verbose > 2) if (verbose > 2)
@ -380,24 +386,29 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore)
range = 0; range = 0;
} }
for (u = lo; u <= hi; u++) { 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]) { if (coll[0]) {
snprintf(usbuf, sizeof usbuf, snprintf(usbuf, sizeof usbuf,
"%s.%s:%s", coll+1, "%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)); 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; break;
case hid_collection: case hid_collection:

View File

@ -42,45 +42,141 @@
#include <usbhid.h> #include <usbhid.h>
#include <dev/usb/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 verbose = 0;
int all = 0;
int noname = 0; int noname = 0;
int hexdump = 0; int hexdump = 0;
int wflag = 0;
int zflag = 0;
char **names; static void usage(void);
int nnames; 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); static void
void usage(void); parceargs(report_desc_t r, int all, int nnames, char **names)
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)
{ {
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++) pnext = &vars;
if (strcmp(names[i], n) == 0) if (all) {
return 1; if (wflag)
return 0; 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 static 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
usage(void) usage(void)
{ {
@ -92,10 +188,14 @@ usage(void)
" %s -f device " " %s -f device "
"[-l] [-n] [-r] [-t tablefile] [-v] [-x] -a\n", "[-l] [-n] [-r] [-t tablefile] [-v] [-x] -a\n",
getprogname()); getprogname());
fprintf(stderr,
" %s -f device "
"[-t tablefile] [-v] [-z] -w name=value\n",
getprogname());
exit(1); exit(1);
} }
void static void
dumpitem(const char *label, struct hid_item *h) dumpitem(const char *label, struct hid_item *h)
{ {
if ((h->flags & HIO_CONST) && !verbose) if ((h->flags & HIO_CONST) && !verbose)
@ -134,7 +234,7 @@ hid_collection_type(int32_t type)
return (num); return (num);
} }
void static void
dumpitems(report_desc_t r) dumpitems(report_desc_t r)
{ {
struct hid_data *d; struct hid_data *d;
@ -174,23 +274,7 @@ dumpitems(report_desc_t r)
printf("Total feature size %d bytes\n", size); printf("Total feature size %d bytes\n", size);
} }
void static 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
prdata(u_char *buf, struct hid_item *h) prdata(u_char *buf, struct hid_item *h)
{ {
u_int data; u_int data;
@ -212,82 +296,162 @@ prdata(u_char *buf, struct hid_item *h)
h->pos = pos; h->pos = pos;
} }
void static void
dumpdata(int f, report_desc_t rd, int loop) dumpdata(int f, report_desc_t rd, int loop)
{ {
struct hid_data *d; struct variable *var;
struct hid_item h, *hids, *n; int dlen, havedata, i, match, r, rid, use_rid;
int r, dlen;
u_char *dbuf; u_char *dbuf;
u_int32_t colls[100]; enum hid_kind kind;
int sp = 0;
char namebuf[10000], *namep;
hids = 0; kind = 0;
for (d = hid_start_parse(rd, 1<<hid_input, -1); rid = -1;
hid_get_item(d, &h); ) { use_rid = !!hid_get_report_id(f);
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");
}
do { do {
r = read(f, dbuf, dlen); if (kind < 3) {
if (r < 1) { if (++rid >= 256) {
err(1, "read error"); rid = 0;
} kind++;
for (n = hids; n; n = n->next) { }
if (n->report_ID != 0 && dbuf[0] != n->report_ID) 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; continue;
namep = namebuf; }
namep += sprintf(namep, "%s:%s.", dlen = hid_report_size(rd, kind < 3 ? kind : hid_input, rid);
hid_usage_page(HID_PAGE(n->collection)), if (dlen <= 0)
hid_usage_in_page(n->collection)); continue;
namep += sprintf(namep, "%s:%s", dbuf = malloc(dlen);
hid_usage_page(HID_PAGE(n->usage)), memset(dbuf, 0, dlen);
hid_usage_in_page(n->usage)); if (kind < 3) {
if (all || gotname(namebuf)) { dbuf[0] = rid;
if (!noname) r = hid_get_report(f, kind, dbuf, dlen);
printf("%s=", namebuf); if (r < 0)
prdata(dbuf, n); 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"); 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"); 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 int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int f;
report_desc_t r; 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 ch;
int repdump = 0; int repdump = 0;
int loop = 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) { switch(ch) {
case 'a': case 'a':
all++; all++;
@ -310,9 +474,15 @@ main(int argc, char **argv)
case 'v': case 'v':
verbose++; verbose++;
break; break;
case 'w':
wflag = 1;
break;
case 'x': case 'x':
hexdump = 1; hexdump = 1;
break; break;
case 'z':
zflag = 1;
break;
case '?': case '?':
default: default:
usage(); usage();
@ -320,12 +490,10 @@ main(int argc, char **argv)
} }
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (dev == 0) if (dev == NULL)
usage(); usage();
names = argv;
nnames = argc;
if (nnames == 0 && !all && !repdump) if (argc == 0 && !all && !repdump)
usage(); usage();
if (dev[0] != '/') { if (dev[0] != '/') {
@ -350,8 +518,13 @@ main(int argc, char **argv)
printf("Report descriptor:\n"); printf("Report descriptor:\n");
dumpitems(r); dumpitems(r);
} }
if (nnames != 0 || all) if (argc != 0 || all) {
dumpdata(f, r, loop); parceargs(r, all, argc, argv);
if (wflag)
writedata(f, r);
else
dumpdata(f, r, loop);
}
hid_dispose_report_desc(r); hid_dispose_report_desc(r);
exit(0); exit(0);

View File

@ -28,7 +28,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd November 23, 2006 .Dd August 01, 2011
.Dt USBHIDCTL 1 .Dt USBHIDCTL 1
.Os .Os
.Sh NAME .Sh NAME
@ -36,27 +36,51 @@
.Nd manipulate USB HID devices .Nd manipulate USB HID devices
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl a
.Fl f Ar device .Fl f Ar device
.Op Fl l
.Op Fl n
.Op Fl r
.Op Fl t Ar table .Op Fl t Ar table
.Op Fl v .Op Fl v
.Op Fl x .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 .Sh DESCRIPTION
The The
.Nm .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 Each named
.Ar item .Ar item
is printed. is printed.
If the
.Fl w
flag is specified
.Nm
attempts to set the specified items to the given values.
.Pp .Pp
The options are as follows: The options are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl a .It Fl a
Show all items. Show all items and their current values if device returns.
.It Fl f Ar device .It Fl f Ar device
Specify a path name for the device to operate on. Specify a path name for the device to operate on.
.It Fl l .It Fl l
@ -69,9 +93,47 @@ Dump the report descriptor.
Specify a path name for the HID usage table file. Specify a path name for the HID usage table file.
.It Fl v .It Fl v
Be verbose. Be verbose.
.It Fl w
Change item values.
Only 'output' and 'feature' kinds can be set with this option.
.It Fl x .It Fl x
Dump data in hexadecimal as well as decimal. 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 .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 .Sh FILES
.Pa /usr/share/misc/usb_hid_usages .Pa /usr/share/misc/usb_hid_usages
The default HID usage table. The default HID usage table.
@ -84,7 +146,3 @@ The
.Nm .Nm
command appeared in command appeared in
.Nx 1.4 . .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"); errx(1, "struct xtty size mismatch");
if (usenumflag || xt->xt_dev == 0 || if (usenumflag || xt->xt_dev == 0 ||
(name = devname(xt->xt_dev, S_IFCHR)) == NULL) (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 else
printf("%10s ", name); printf("%10s ", name);
printf("%5zu %4zu %4zu %4zu %5zu %4zu %4zu %5u %5d %5d ", printf("%5zu %4zu %4zu %4zu %5zu %4zu %4zu %5u %5d %5d ",