Merge ^/head r357119 through r357178.

This commit is contained in:
Dimitry Andric 2020-01-27 20:47:18 +00:00
commit 773bec0868
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/clang1000-import/; revision=357179
56 changed files with 717 additions and 359 deletions

View File

@ -32,7 +32,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd March 7, 2017 .Dd January 26, 2020
.Dt PWAIT 1 .Dt PWAIT 1
.Os .Os
.Sh NAME .Sh NAME
@ -41,7 +41,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl t Ar duration .Op Fl t Ar duration
.Op Fl v .Op Fl ov
.Ar pid .Ar pid
\&... \&...
.Sh DESCRIPTION .Sh DESCRIPTION
@ -51,6 +51,8 @@ utility will wait until each of the given processes has terminated.
.Pp .Pp
The following option is available: The following option is available:
.Bl -tag -width indent .Bl -tag -width indent
.It Fl o
Exit when any of the given processes has terminated.
.It Fl t Ar duration .It Fl t Ar duration
If any process is still running after If any process is still running after
.Ar duration , .Ar duration ,

View File

@ -53,8 +53,7 @@ static void
usage(void) usage(void)
{ {
fprintf(stderr, "usage: pwait [-t timeout] [-v] pid ...\n"); errx(EX_USAGE, "usage: pwait [-t timeout] [-ov] pid ...");
exit(EX_USAGE);
} }
/* /*
@ -64,25 +63,30 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
struct itimerval itv; struct itimerval itv;
int kq;
struct kevent *e; struct kevent *e;
int tflag, verbose; int oflag, tflag, verbose;
int opt, nleft, n, i, duplicate, status; int i, kq, n, nleft, opt, status;
long pid; long pid;
char *s, *end; char *end, *s;
double timeout; double timeout;
tflag = verbose = 0; oflag = 0;
tflag = 0;
verbose = 0;
memset(&itv, 0, sizeof(itv)); memset(&itv, 0, sizeof(itv));
while ((opt = getopt(argc, argv, "t:v")) != -1) {
while ((opt = getopt(argc, argv, "ot:v")) != -1) {
switch (opt) { switch (opt) {
case 'o':
oflag = 1;
break;
case 't': case 't':
tflag = 1; tflag = 1;
errno = 0; errno = 0;
timeout = strtod(optarg, &end); timeout = strtod(optarg, &end);
if (end == optarg || errno == ERANGE || if (end == optarg || errno == ERANGE || timeout < 0) {
timeout < 0)
errx(EX_DATAERR, "timeout value"); errx(EX_DATAERR, "timeout value");
}
switch(*end) { switch(*end) {
case 0: case 0:
case 's': case 's':
@ -96,8 +100,9 @@ main(int argc, char *argv[])
default: default:
errx(EX_DATAERR, "timeout unit"); errx(EX_DATAERR, "timeout unit");
} }
if (timeout > 100000000L) if (timeout > 100000000L) {
errx(EX_DATAERR, "timeout value"); errx(EX_DATAERR, "timeout value");
}
itv.it_value.tv_sec = (time_t)timeout; itv.it_value.tv_sec = (time_t)timeout;
timeout -= (time_t)timeout; timeout -= (time_t)timeout;
itv.it_value.tv_usec = itv.it_value.tv_usec =
@ -115,77 +120,96 @@ main(int argc, char *argv[])
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (argc == 0) if (argc == 0) {
usage(); usage();
}
kq = kqueue(); kq = kqueue();
if (kq == -1) if (kq == -1) {
err(1, "kqueue"); err(EX_OSERR, "kqueue");
}
e = malloc((argc + tflag) * sizeof(struct kevent)); e = malloc((argc + tflag) * sizeof(struct kevent));
if (e == NULL) if (e == NULL) {
err(1, "malloc"); err(EX_OSERR, "malloc");
}
nleft = 0; nleft = 0;
for (n = 0; n < argc; n++) { for (n = 0; n < argc; n++) {
s = argv[n]; s = argv[n];
if (!strncmp(s, "/proc/", 6)) /* Undocumented Solaris compat */ /* Undocumented Solaris compat */
if (!strncmp(s, "/proc/", 6)) {
s += 6; s += 6;
}
errno = 0; errno = 0;
pid = strtol(s, &end, 10); pid = strtol(s, &end, 10);
if (pid < 0 || *end != '\0' || errno != 0) { if (pid < 0 || *end != '\0' || errno != 0) {
warnx("%s: bad process id", s); warnx("%s: bad process id", s);
continue; continue;
} }
duplicate = 0; for (i = 0; i < nleft; i++) {
for (i = 0; i < nleft; i++) if (e[i].ident == (uintptr_t)pid) {
if (e[i].ident == (uintptr_t)pid) break;
duplicate = 1; }
if (!duplicate) { }
EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, if (i < nleft) {
0, NULL); /* Duplicate. */
if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) continue;
warn("%ld", pid); }
else EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
nleft++; if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) {
warn("%ld", pid);
if (oflag) {
exit(EX_OK);
}
} else {
nleft++;
} }
} }
if (tflag) { if (nleft > 0 && tflag) {
/* /*
* Explicitly detect SIGALRM so that an exit status of 124 * Explicitly detect SIGALRM so that an exit status of 124
* can be returned rather than 142. * can be returned rather than 142.
*/ */
EV_SET(e + nleft, SIGALRM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); EV_SET(e + nleft, SIGALRM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) {
err(EX_OSERR, "kevent"); err(EX_OSERR, "kevent");
}
/* Ignore SIGALRM to not interrupt kevent(2). */ /* Ignore SIGALRM to not interrupt kevent(2). */
signal(SIGALRM, SIG_IGN); signal(SIGALRM, SIG_IGN);
if (setitimer(ITIMER_REAL, &itv, NULL) == -1) if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
err(EX_OSERR, "setitimer"); err(EX_OSERR, "setitimer");
}
} }
while (nleft > 0) { while (nleft > 0) {
n = kevent(kq, NULL, 0, e, nleft + tflag, NULL); n = kevent(kq, NULL, 0, e, nleft + tflag, NULL);
if (n == -1) if (n == -1) {
err(1, "kevent"); err(EX_OSERR, "kevent");
}
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (e[i].filter == EVFILT_SIGNAL) { if (e[i].filter == EVFILT_SIGNAL) {
if (verbose) if (verbose) {
printf("timeout\n"); printf("timeout\n");
return (124); }
exit(124);
} }
if (verbose) { if (verbose) {
status = e[i].data; status = e[i].data;
if (WIFEXITED(status)) if (WIFEXITED(status)) {
printf("%ld: exited with status %d.\n", printf("%ld: exited with status %d.\n",
(long)e[i].ident, (long)e[i].ident,
WEXITSTATUS(status)); WEXITSTATUS(status));
else if (WIFSIGNALED(status)) } else if (WIFSIGNALED(status)) {
printf("%ld: killed by signal %d.\n", printf("%ld: killed by signal %d.\n",
(long)e[i].ident, (long)e[i].ident,
WTERMSIG(status)); WTERMSIG(status));
else } else {
printf("%ld: terminated.\n", printf("%ld: terminated.\n",
(long)e[i].ident); (long)e[i].ident);
}
}
if (oflag) {
exit(EX_OK);
} }
--nleft; --nleft;
} }

View File

@ -232,6 +232,85 @@ timeout_many_cleanup()
wait $p1 $p5 $p10 >/dev/null 2>&1 wait $p1 $p5 $p10 >/dev/null 2>&1
} }
atf_test_case or_flag
or_flag_head()
{
atf_set "descr" "Test OR flag"
}
or_flag_body()
{
sleep 2 &
p2=$!
sleep 4 &
p4=$!
sleep 6 &
p6=$!
atf_check \
-o inline:"$p2: exited with status 0.\n" \
-e empty \
-s exit:0 \
timeout --preserve-status 15 pwait -o -v $p2 $p4 $p6
atf_check \
-o empty \
-e inline:"pwait: $p2: No such process\n" \
-s exit:0 \
timeout --preserve-status 15 pwait -o $p2 $p4 $p6
atf_check \
-o empty \
-e empty \
-s exit:0 \
timeout --preserve-status 15 pwait -o $p4 $p6
atf_check \
-o empty \
-e inline:"pwait: $p4: No such process\n" \
-s exit:0 \
timeout --preserve-status 15 pwait -o $p4 $p6
atf_check \
-o inline:"$p6: exited with status 0.\n" \
-e empty \
-s exit:0 \
timeout --preserve-status 15 pwait -o -v $p6
atf_check \
-o empty \
-e inline:"pwait: $p6: No such process\n" \
-s exit:0 \
timeout --preserve-status 15 pwait -o $p6
atf_check \
-o empty \
-e inline:"kill: $p2: No such process\n" \
-s exit:1 \
kill -0 $p2
atf_check \
-o empty \
-e inline:"kill: $p4: No such process\n" \
-s exit:1 \
kill -0 $p4
atf_check \
-o empty \
-e inline:"kill: $p6: No such process\n" \
-s exit:1 \
kill -0 $p6
}
or_flag_cleanup()
{
kill $p2 $p4 $p6 >/dev/null 2>&1
wait $p2 $p4 $p6 >/dev/null 2>&1
}
atf_init_test_cases() atf_init_test_cases()
{ {
atf_add_test_case basic atf_add_test_case basic
@ -239,4 +318,5 @@ atf_init_test_cases()
atf_add_test_case timeout_trigger_timeout atf_add_test_case timeout_trigger_timeout
atf_add_test_case timeout_no_timeout atf_add_test_case timeout_no_timeout
atf_add_test_case timeout_many atf_add_test_case timeout_many
atf_add_test_case or_flag
} }

View File

@ -12,7 +12,7 @@
# #
AC_PREREQ(2.2) AC_PREREQ(2.2)
AC_INIT([libxo], [1.3.1], [phil@juniper.net]) AC_INIT([libxo], [1.4.0], [phil@juniper.net])
AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability]) AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
# Support silent build rules. Requires at least automake-1.11. # Support silent build rules. Requires at least automake-1.11.

View File

@ -1204,6 +1204,11 @@ message associated with either *errno* or the *code* parameter::
xo_err(1, "cannot open file '%s'", filename); xo_err(1, "cannot open file '%s'", filename);
.. index:: xo_error .. index:: xo_error
.. index:: xo_error_h
.. index:: xo_error_hv
.. index:: xo_errorn
.. index:: xo_errorn_h
.. index:: xo_errorn_hv
xo_error xo_error
~~~~~~~~ ~~~~~~~~
@ -1214,6 +1219,50 @@ xo_error
:type fmt: const char * :type fmt: const char *
:returns: void :returns: void
.. c:function:: void xo_error_h (xo_handle_t *xop, const char *fmt, ...)
:param xop: libxo handle pointer
:type xop: xo_handle_t *
:param fmt: Format string
:type fmt: const char *
:returns: void
.. c:function:: void xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
:param xop: libxo handle pointer
:type xop: xo_handle_t *
:param fmt: Format string
:type fmt: const char *
:param vap: variadic arguments
:type xop: va_list
:returns: void
.. c:function:: void xo_errorn (const char *fmt, ...)
:param fmt: Format string
:type fmt: const char *
:returns: void
.. c:function:: void xo_errorn_h (xo_handle_t *xop, const char *fmt, ...)
:param xop: libxo handle pointer
:type xop: xo_handle_t *
:param fmt: Format string
:type fmt: const char *
:returns: void
.. c:function:: void xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap)
:param xop: libxo handle pointer
:type xop: xo_handle_t *
:param need_newline: boolean indicating need for trailing newline
:type need_newline: int
:param fmt: Format string
:type fmt: const char *
:param vap: variadic arguments
:type xop: va_list
:returns: void
The `xo_error` function can be used for generic errors that should The `xo_error` function can be used for generic errors that should
be reported over the handle, rather than to stderr. The `xo_error` be reported over the handle, rather than to stderr. The `xo_error`
function behaves like `xo_err` for TEXT and HTML output styles, but function behaves like `xo_err` for TEXT and HTML output styles, but
@ -1226,6 +1275,16 @@ xo_error
JSON:: JSON::
"error": { "message": "Does not compute" } "error": { "message": "Does not compute" }
The `xo_error_h` and `xo_error_hv` add a handle object and a
variadic-ized parameter to the signature, respectively.
The `xo_errorn` function supplies a newline at the end the error
message if the format string does not include one. The
`xo_errorn_h` and `xo_errorn_hv` functions add a handle object and
a variadic-ized parameter to the signature, respectively. The
`xo_errorn_hv` function also adds a boolean to indicate the need for
a trailing newline.
.. index:: xo_no_setlocale .. index:: xo_no_setlocale
.. index:: Locale .. index:: Locale

View File

@ -26,12 +26,13 @@ example uses the "cbor" encoder, saving the output into a file::
df --libxo encoder=cbor > df-output.cbor df --libxo encoder=cbor > df-output.cbor
Encoders can support specific options that can be accessed by Encoders can support specific options that can be accessed by
following the encoder name with a colon (':') and one of more options, following the encoder name with a colon (':') or a plus sign ('+') and
separated by a plus sign "+":: one of more options, separated by the same character::
df --libxo encoder=csv:path=filesystem+leaf=name+no-header df --libxo encoder=csv+path=filesystem+leaf=name+no-header
df --libxo encoder=csv:path=filesystem:leaf=name:no-header
This example instructs libxo to load the "csv" encoder and pass the These examples instructs libxo to load the "csv" encoder and pass the
following options:: following options::
path=filesystem path=filesystem
@ -42,6 +43,10 @@ Each of these option is interpreted by the encoder, and all such
options names and semantics are specific to the particular encoder. options names and semantics are specific to the particular encoder.
Refer to the intended encoder for documentation on its options. Refer to the intended encoder for documentation on its options.
The string "@" can be used in place of the string "encoder=".
df --libxo @csv:no-header
.. _csv_encoder: .. _csv_encoder:
CSV - Comma Separated Values CSV - Comma Separated Values

View File

@ -162,3 +162,23 @@ foreground and background output to "yellow", give only the fifth
mapping, skipping the first four mappings with bare plus signs ("+"):: mapping, skipping the first four mappings with bare plus signs ("+")::
--libxo colors=++++yellow/yellow --libxo colors=++++yellow/yellow
Encoders
--------
In addition to the four "built-in" formats, libxo supports an
extensible mechanism for adding encoders. These are activated
using the "encoder" keyword::
--libxo encoder=cbor
The encoder can include encoder-specific options, separated by either
colons (":") or plus signs ("+"):
--libxo encoder=csv+path=filesystem+leaf=name+no-header
--libxo encoder=csv:path=filesystem:leaf=name:no-header
For brevity, the string "@" can be used in place of the string
"encoder=".
df --libxo @csv:no-header

View File

@ -41,10 +41,12 @@
* (double) quote characters. * (double) quote characters.
* - Leading and trialing whitespace require fields be quoted. * - Leading and trialing whitespace require fields be quoted.
* *
* Cheesy, but simple. The RFC also requires MS-DOS end-of-line, which * Cheesy, but simple. The RFC also requires MS-DOS end-of-line,
* we only do with the "dos" option. Strange that we still live in a * which we only do with the "dos" option. Strange that we still live
* DOS-friendly world, but then again, we make spaceships based on the * in a DOS-friendly world, but then again, we make spaceships based
* horse butts (http://www.astrodigital.org/space/stshorse.html). * on the horse butts (http://www.astrodigital.org/space/stshorse.html
* though the "built by English expatriates” bit is rubbish; better to
* say the first engines used in America were built by Englishmen.)
*/ */
#include <string.h> #include <string.h>
@ -655,10 +657,12 @@ csv_record_path (xo_handle_t *xop, csv_private_t *csv, const char *path_raw)
/* /*
* Extract the option values. The format is: * Extract the option values. The format is:
* -libxo encoder=csv:kw=val+kw=val+kw=val,pretty,etc * -libxo encoder=csv:kw=val:kw=val:kw=val,pretty
* -libxo encoder=csv+kw=val+kw=val+kw=val,pretty
*/ */
static int static int
csv_options (xo_handle_t *xop, csv_private_t *csv, const char *raw_opts) csv_options (xo_handle_t *xop, csv_private_t *csv,
const char *raw_opts, char opts_char)
{ {
ssize_t len = strlen(raw_opts); ssize_t len = strlen(raw_opts);
char *options = alloca(len + 1); char *options = alloca(len + 1);
@ -667,7 +671,7 @@ csv_options (xo_handle_t *xop, csv_private_t *csv, const char *raw_opts)
char *cp, *ep, *np, *vp; char *cp, *ep, *np, *vp;
for (cp = options, ep = options + len + 1; cp && cp < ep; cp = np) { for (cp = options, ep = options + len + 1; cp && cp < ep; cp = np) {
np = strchr(cp, '+'); np = strchr(cp, opts_char);
if (np) if (np)
*np++ = '\0'; *np++ = '\0';
@ -761,7 +765,11 @@ csv_handler (XO_ENCODER_HANDLER_ARGS)
break; break;
case XO_OP_OPTIONS: case XO_OP_OPTIONS:
rc = csv_options(xop, csv, value); rc = csv_options(xop, csv, value, ':');
break;
case XO_OP_OPTIONS_PLUS:
rc = csv_options(xop, csv, value, '+');
break; break;
case XO_OP_OPEN_LIST: case XO_OP_OPEN_LIST:

View File

@ -2371,6 +2371,25 @@ xo_set_options (xo_handle_t *xop, const char *input)
if (np) if (np)
*np++ = '\0'; *np++ = '\0';
/*
* "@foo" is a shorthand for "encoder=foo". This is driven
* chiefly by a desire to make pluggable encoders not appear
* so distinct from built-in encoders.
*/
if (*cp == '@') {
vp = cp + 1;
if (*vp == '\0')
xo_failure(xop, "missing value for encoder option");
else {
rc = xo_encoder_init(xop, vp);
if (rc)
xo_warnx("error initializing encoder: %s", vp);
}
continue;
}
vp = strchr(cp, '='); vp = strchr(cp, '=');
if (vp) if (vp)
*vp++ = '\0'; *vp++ = '\0';
@ -8007,7 +8026,7 @@ xo_finish_atexit (void)
* Generate an error message, such as would be displayed on stderr * Generate an error message, such as would be displayed on stderr
*/ */
void void
xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap) xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap)
{ {
xop = xo_default(xop); xop = xo_default(xop);
@ -8015,13 +8034,15 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
* If the format string doesn't end with a newline, we pop * If the format string doesn't end with a newline, we pop
* one on ourselves. * one on ourselves.
*/ */
ssize_t len = strlen(fmt); if (need_newline) {
if (len > 0 && fmt[len - 1] != '\n') { ssize_t len = strlen(fmt);
char *newfmt = alloca(len + 2); if (len > 0 && fmt[len - 1] != '\n') {
memcpy(newfmt, fmt, len); char *newfmt = alloca(len + 2);
newfmt[len] = '\n'; memcpy(newfmt, fmt, len);
newfmt[len + 1] = '\0'; newfmt[len] = '\n';
fmt = newfmt; newfmt[len + 1] = '\0';
fmt = newfmt;
}
} }
switch (xo_style(xop)) { switch (xo_style(xop)) {
@ -8069,7 +8090,7 @@ xo_error_h (xo_handle_t *xop, const char *fmt, ...)
va_list vap; va_list vap;
va_start(vap, fmt); va_start(vap, fmt);
xo_error_hv(xop, fmt, vap); xo_errorn_hv(xop, 0, fmt, vap);
va_end(vap); va_end(vap);
} }
@ -8082,7 +8103,30 @@ xo_error (const char *fmt, ...)
va_list vap; va_list vap;
va_start(vap, fmt); va_start(vap, fmt);
xo_error_hv(NULL, fmt, vap); xo_errorn_hv(NULL, 0, fmt, vap);
va_end(vap);
}
void
xo_errorn_h (xo_handle_t *xop, const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_errorn_hv(xop, 1, fmt, vap);
va_end(vap);
}
/*
* Generate an error message, such as would be displayed on stderr
*/
void
xo_errorn (const char *fmt, ...)
{
va_list vap;
va_start(vap, fmt);
xo_errorn_hv(NULL, 1, fmt, vap);
va_end(vap); va_end(vap);
} }
@ -8099,21 +8143,30 @@ xo_parse_args (int argc, char **argv)
char *cp; char *cp;
int i, save; int i, save;
/* Save our program name for xo_err and friends */ /*
xo_program = argv[0]; * If xo_set_program has always been called, we honor that value
cp = strrchr(xo_program, '/'); */
if (cp) if (xo_program == NULL) {
xo_program = ++cp; /* Save our program name for xo_err and friends */
else xo_program = argv[0];
cp = argv[0]; /* Reset to front of string */ cp = strrchr(xo_program, '/');
if (cp)
xo_program = ++cp;
else
cp = argv[0]; /* Reset to front of string */
/* GNU tools add an annoying ".test" as the program extension; remove it */ /*
size_t len = strlen(xo_program); * GNU libtool add an annoying ".test" as the program
static const char gnu_ext[] = ".test"; * extension; we remove it. libtool also adds a "lt-" prefix
if (len >= sizeof(gnu_ext)) { * that we cannot remove.
cp += len + 1 - sizeof(gnu_ext); */
if (xo_streq(cp, gnu_ext)) size_t len = strlen(xo_program);
*cp = '\0'; static const char gnu_ext[] = ".test";
if (len >= sizeof(gnu_ext)) {
cp += len + 1 - sizeof(gnu_ext);
if (xo_streq(cp, gnu_ext))
*cp = '\0';
}
} }
xo_handle_t *xop = xo_default(NULL); xo_handle_t *xop = xo_default(NULL);

View File

@ -389,6 +389,15 @@ xo_error_h (xo_handle_t *xop, const char *fmt, ...);
void void
xo_error (const char *fmt, ...); xo_error (const char *fmt, ...);
void
xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap);
void
xo_errorn_h (xo_handle_t *xop, const char *fmt, ...);
void
xo_errorn (const char *fmt, ...);
xo_ssize_t xo_ssize_t
xo_flush_h (xo_handle_t *xop); xo_flush_h (xo_handle_t *xop);

View File

@ -290,8 +290,21 @@ xo_encoder_init (xo_handle_t *xop, const char *name)
{ {
xo_encoder_setup(); xo_encoder_setup();
const char *opts = strchr(name, ':'); char opts_char = '\0';
const char *col_opts = strchr(name, ':');
const char *plus_opts = strchr(name, '+');
/*
* Find the option-separating character (plus or colon) which
* appears first in the options string.
*/
const char *opts = (col_opts == NULL) ? plus_opts
: (plus_opts == NULL) ? col_opts
: (plus_opts < col_opts) ? plus_opts : col_opts;
if (opts) { if (opts) {
opts_char = *opts;
/* Make a writable copy of the name */ /* Make a writable copy of the name */
size_t len = strlen(name); size_t len = strlen(name);
char *copy = alloca(len + 1); char *copy = alloca(len + 1);
@ -329,7 +342,11 @@ xo_encoder_init (xo_handle_t *xop, const char *name)
int rc = xo_encoder_handle(xop, XO_OP_CREATE, name, NULL, 0); int rc = xo_encoder_handle(xop, XO_OP_CREATE, name, NULL, 0);
if (rc == 0 && opts != NULL) { if (rc == 0 && opts != NULL) {
rc = xo_encoder_handle(xop, XO_OP_OPTIONS, name, opts, 0); xo_encoder_op_t op;
/* Encoder API is limited, so we're stuck with two different options */
op = (opts_char == '+') ? XO_OP_OPTIONS_PLUS : XO_OP_OPTIONS;
rc = xo_encoder_handle(xop, op, name, opts, 0);
} }
return rc; return rc;

View File

@ -90,6 +90,7 @@ typedef unsigned xo_encoder_op_t;
#define XO_OP_ATTRIBUTE 15 /* Attribute name/value */ #define XO_OP_ATTRIBUTE 15 /* Attribute name/value */
#define XO_OP_VERSION 16 /* Version string */ #define XO_OP_VERSION 16 /* Version string */
#define XO_OP_OPTIONS 17 /* Additional command line options */ #define XO_OP_OPTIONS 17 /* Additional command line options */
#define XO_OP_OPTIONS_PLUS 18 /* Additional command line options */
#define XO_ENCODER_HANDLER_ARGS \ #define XO_ENCODER_HANDLER_ARGS \
xo_handle_t *xop __attribute__ ((__unused__)), \ xo_handle_t *xop __attribute__ ((__unused__)), \

View File

@ -88,7 +88,7 @@ TEST_JIG = \
TEST_JIG2 = \ TEST_JIG2 = \
echo "... $$test ... $$fmt ..."; \ echo "... $$test ... $$fmt ..."; \
xoopts==warn,encoder=csv$$csv ; \ xoopts==warn,$$csv ; \
${TEST_JIG}; true; ${TEST_JIG}; true;
TEST_FORMATS = T XP JP HP X J H HIPx TEST_FORMATS = T XP JP HP X J H HIPx
@ -111,9 +111,12 @@ test tests: ${bin_PROGRAMS}
done) \ done) \
done) done)
-@ (${TEST_TRACE} test=test_01.c; base=test_01; \ -@ (${TEST_TRACE} test=test_01.c; base=test_01; \
( fmt=Ecsv1; csv= ; ${TEST_JIG2} ); \ ( fmt=Ecsv1; csv=encoder=csv ; \
( fmt=Ecsv2; csv=:path=top/data/item+no-header ; ${TEST_JIG2} ); \ ${TEST_JIG2} ); \
( fmt=Ecsv3; csv=:path=item+leafs=sku.sold+no-quotes ; ${TEST_JIG2} ); \ ( fmt=Ecsv2; csv=encoder=csv:path=top/data/item:no-header ; \
${TEST_JIG2} ); \
( fmt=Ecsv3; csv=@csv:path=item:leafs=sku.sold:no-quotes ; \
${TEST_JIG2} ); \
) )

File diff suppressed because one or more lines are too long

View File

@ -225,3 +225,18 @@
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt; <div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</div> </div>
</div> </div>
<div class="line">
<div class="error">err message (1)</div>
</div>
<div class="line">
<div class="error">err message (2)
</div>
</div>
<div class="line">
<div class="error">err message (1)
</div>
</div>
<div class="line">
<div class="error">err message (2)
</div>
</div>

View File

@ -225,3 +225,18 @@
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt; <div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</div> </div>
</div> </div>
<div class="line">
<div class="error">err message (1)</div>
</div>
<div class="line">
<div class="error">err message (2)
</div>
</div>
<div class="line">
<div class="error">err message (1)
</div>
</div>
<div class="line">
<div class="error">err message (2)
</div>
</div>

View File

@ -1 +1 @@
{"top": {"data": {"name":"em0","flags":"0x8843","name":"em0","flags":"0x8843","what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}}}} {"top": {"data": {"name":"em0","flags":"0x8843","name":"em0","flags":"0x8843","what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"}, "error": {"message":"err message (1)"}, "error": {"message":"err message (2)\n"}, "error": {"message":"err message (1)\n"}, "error": {"message":"err message (2)\n"}}}}

View File

@ -80,6 +80,18 @@
"test": 4, "test": 4,
"error": { "error": {
"message": "Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n" "message": "Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"
},
"error": {
"message": "err message (1)"
},
"error": {
"message": "err message (2)\n"
},
"error": {
"message": "err message (1)\n"
},
"error": {
"message": "err message (2)\n"
} }
} }
} }

View File

@ -1,2 +1,5 @@
test_02: key field emitted after normal value field: 'name' test_02: key field emitted after normal value field: 'name'
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<> Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
err message (1)err message (2)
err message (1)
err message (2)

View File

@ -4,4 +4,7 @@
</message><length>abcdef</length><fd>-1</fd><error>Bad file descriptor</error><test>good</test><fd>-1</fd><error>Bad fi</error><test>good</test><message>improper use of profanity; ten yard penalty; first down </message><length>abcdef</length><fd>-1</fd><error>Bad file descriptor</error><test>good</test><fd>-1</fd><error>Bad fi</error><test>good</test><message>improper use of profanity; ten yard penalty; first down
</message><lines>20</lines><words>30</words><characters>40</characters><bytes>0</bytes><bytes>1</bytes><bytes>2</bytes><bytes>3</bytes><bytes>4</bytes><mbuf-current>10</mbuf-current><mbuf-cache>20</mbuf-cache><mbuf-total>30</mbuf-total><distance units="miles">50</distance><location>Boston</location><memory units="k">64</memory><total units="kb">640</total><memory units="k">64</memory><total units="kilobytes">640</total><ten>10</ten><eleven>11</eleven><unknown>1010</unknown><unknown>1010</unknown><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><val1>21</val1><val2>58368</val2><val3>100663296</val3><val4>44470272</val4><val5>1342172800</val5><flag>one</flag><flag>two</flag><flag>three</flag><works>null</works><empty-tag></empty-tag><t1>1000</t1><t2>test5000</t2><t3>ten-longx</t3><t4>xtest</t4><__error><message>this is an error</message></__error><__error><message>two more errors</message></__error><__warning><message>this is an warning</message></__warning><__warning><message>two more warnings</message></__warning><count>10</count><test>4</test><message>improper use of profanity; ten yard penalty; first down </message><lines>20</lines><words>30</words><characters>40</characters><bytes>0</bytes><bytes>1</bytes><bytes>2</bytes><bytes>3</bytes><bytes>4</bytes><mbuf-current>10</mbuf-current><mbuf-cache>20</mbuf-cache><mbuf-total>30</mbuf-total><distance units="miles">50</distance><location>Boston</location><memory units="k">64</memory><total units="kb">640</total><memory units="k">64</memory><total units="kilobytes">640</total><ten>10</ten><eleven>11</eleven><unknown>1010</unknown><unknown>1010</unknown><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><min>15</min><cur>20</cur><max>125</max><val1>21</val1><val2>58368</val2><val3>100663296</val3><val4>44470272</val4><val5>1342172800</val5><flag>one</flag><flag>two</flag><flag>three</flag><works>null</works><empty-tag></empty-tag><t1>1000</t1><t2>test5000</t2><t3>ten-longx</t3><t4>xtest</t4><__error><message>this is an error</message></__error><__error><message>two more errors</message></__error><__warning><message>this is an warning</message></__warning><__warning><message>two more warnings</message></__warning><count>10</count><test>4</test><message>improper use of profanity; ten yard penalty; first down
</message><error><message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt; </message><error><message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</message></error><error><message>err message (1)</message></error><error><message>err message (2)
</message></error><error><message>err message (1)
</message></error><error><message>err message (2)
</message></error></data></top> </message></error></data></top>

View File

@ -85,6 +85,21 @@
</message> </message>
<error> <error>
<message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt; <message>Shut 'er down, Clancey! She's a-pumpin' mud! &lt;&gt;!,"!&lt;&gt;
</message>
</error>
<error>
<message>err message (1)</message>
</error>
<error>
<message>err message (2)
</message>
</error>
<error>
<message>err message (1)
</message>
</error>
<error>
<message>err message (2)
</message> </message>
</error> </error>
</data> </data>

View File

@ -21,6 +21,8 @@
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
xo_set_program("test_02");
argc = xo_parse_args(argc, argv); argc = xo_parse_args(argc, argv);
if (argc < 0) if (argc < 0)
return 1; return 1;
@ -144,6 +146,10 @@ main (int argc, char **argv)
"ten yard penalty", "first down"); "ten yard penalty", "first down");
xo_error("Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n"); xo_error("Shut 'er down, Clancey! She's a-pumpin' mud! <>!,\"!<>\n");
xo_error("err message (%d)", 1);
xo_error("err message (%d)\n", 2);
xo_errorn("err message (%d)", 1);
xo_errorn("err message (%d)\n", 2);
xo_close_container("data"); xo_close_container("data");

View File

@ -25,6 +25,8 @@ main (int argc, char **argv)
xo_emit_flags_t flags = XOEF_RETAIN; xo_emit_flags_t flags = XOEF_RETAIN;
int opt_color = 1; int opt_color = 1;
xo_set_program("test_12");
argc = xo_parse_args(argc, argv); argc = xo_parse_args(argc, argv);
if (argc < 0) if (argc < 0)
return 1; return 1;

View File

@ -3,10 +3,10 @@
.Fx .Fx
uses uses
.Nm libxo .Nm libxo
version 1.3.1. version 1.4.0.
Complete documentation can be found on github: Complete documentation can be found on github:
.Bd -literal -offset indent .Bd -literal -offset indent
https://juniper.github.io/libxo/1.3.1/html/index.html https://juniper.github.io/libxo/1.4.0/html/index.html
.Ed .Ed
.Pp .Pp
.Nm libxo .Nm libxo

View File

@ -183,16 +183,16 @@
/* #undef LIBXO_TEXT_ONLY */ /* #undef LIBXO_TEXT_ONLY */
/* Version number as dotted value */ /* Version number as dotted value */
#define LIBXO_VERSION "1.3.1" #define LIBXO_VERSION "1.4.0"
/* Version number extra information */ /* Version number extra information */
#define LIBXO_VERSION_EXTRA "" #define LIBXO_VERSION_EXTRA ""
/* Version number as a number */ /* Version number as a number */
#define LIBXO_VERSION_NUMBER 1003001 #define LIBXO_VERSION_NUMBER 1004000
/* Version number as string */ /* Version number as string */
#define LIBXO_VERSION_STRING "1003001" #define LIBXO_VERSION_STRING "1004000"
/* Enable local wcwidth implementation */ /* Enable local wcwidth implementation */
#define LIBXO_WCWIDTH 1 #define LIBXO_WCWIDTH 1
@ -210,7 +210,7 @@
#define PACKAGE_NAME "libxo" #define PACKAGE_NAME "libxo"
/* Define to the full name and version of this package. */ /* Define to the full name and version of this package. */
#define PACKAGE_STRING "libxo 1.3.1" #define PACKAGE_STRING "libxo 1.4.0"
/* Define to the one symbol short name of this package. */ /* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libxo" #define PACKAGE_TARNAME "libxo"
@ -219,7 +219,7 @@
#define PACKAGE_URL "" #define PACKAGE_URL ""
/* Define to the version of this package. */ /* Define to the version of this package. */
#define PACKAGE_VERSION "1.3.1" #define PACKAGE_VERSION "1.4.0"
/* If using the C implementation of alloca, define if you know the /* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be direction of stack growth for your system; otherwise it will be
@ -236,7 +236,7 @@
/* #undef USE_INT_RETURN_CODES */ /* #undef USE_INT_RETURN_CODES */
/* Version number of package */ /* Version number of package */
#define VERSION "1.3.1" #define VERSION "1.4.0"
/* Retain hash bucket size */ /* Retain hash bucket size */
/* #undef XO_RETAIN_SIZE */ /* #undef XO_RETAIN_SIZE */

View File

@ -31,10 +31,15 @@ static const char rcsid[] =
#endif /* not lint */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#ifdef MAKEFS
/* In the makefs case we only want struct disklabel */
#include <sys/disk/bsd.h>
#else
#include <sys/fdcio.h> #include <sys/fdcio.h>
#include <sys/disk.h> #include <sys/disk.h>
#include <sys/disklabel.h> #include <sys/disklabel.h>
#include <sys/mount.h> #include <sys/mount.h>
#endif
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
@ -285,14 +290,18 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
if (!S_ISREG(sb.st_mode)) if (!S_ISREG(sb.st_mode))
warnx("warning, %s is not a regular file", fname); warnx("warning, %s is not a regular file", fname);
} else { } else {
#ifndef MAKEFS #ifdef MAKEFS
errx(1, "o.create_size must be set!");
#else
if (!S_ISCHR(sb.st_mode)) if (!S_ISCHR(sb.st_mode))
warnx("warning, %s is not a character device", fname); warnx("warning, %s is not a character device", fname);
#endif #endif
} }
#ifndef MAKEFS
if (!o.no_create) if (!o.no_create)
if (check_mounted(fname, sb.st_mode) == -1) if (check_mounted(fname, sb.st_mode) == -1)
goto done; goto done;
#endif
if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) { if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) {
warnx("cannot seek to %jd", (intmax_t)o.offset); warnx("cannot seek to %jd", (intmax_t)o.offset);
goto done; goto done;
@ -621,10 +630,12 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
bpb.bpbBigFATsecs) * bpb.bpbFATs; bpb.bpbBigFATsecs) * bpb.bpbFATs;
memset(&si_sa, 0, sizeof(si_sa)); memset(&si_sa, 0, sizeof(si_sa));
si_sa.sa_handler = infohandler; si_sa.sa_handler = infohandler;
#ifdef SIGINFO
if (sigaction(SIGINFO, &si_sa, NULL) == -1) { if (sigaction(SIGINFO, &si_sa, NULL) == -1) {
warn("sigaction SIGINFO"); warn("sigaction SIGINFO");
goto done; goto done;
} }
#endif
for (lsn = 0; lsn < dir + (fat == 32 ? bpb.bpbSecPerClust : rds); lsn++) { for (lsn = 0; lsn < dir + (fat == 32 ? bpb.bpbSecPerClust : rds); lsn++) {
if (got_siginfo) { if (got_siginfo) {
fprintf(stderr,"%s: writing sector %u of %u (%u%%)\n", fprintf(stderr,"%s: writing sector %u of %u (%u%%)\n",
@ -766,6 +777,11 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
static int static int
check_mounted(const char *fname, mode_t mode) check_mounted(const char *fname, mode_t mode)
{ {
/*
* If getmntinfo() is not available (e.g. Linux) don't check. This should
* not be a problem since we will only be using makefs to create images.
*/
#if !defined(MAKEFS)
struct statfs *mp; struct statfs *mp;
const char *s1, *s2; const char *s1, *s2;
size_t len; size_t len;
@ -790,6 +806,7 @@ check_mounted(const char *fname, mode_t mode)
return -1; return -1;
} }
} }
#endif
return 0; return 0;
} }
@ -811,6 +828,23 @@ getstdfmt(const char *fmt, struct bpb *bpb)
return 0; return 0;
} }
static void
compute_geometry_from_file(int fd, const char *fname, struct disklabel *lp)
{
struct stat st;
off_t ms;
if (fstat(fd, &st))
err(1, "cannot get disk size");
if (!S_ISREG(st.st_mode))
errx(1, "%s is not a regular file", fname);
ms = st.st_size;
lp->d_secsize = 512;
lp->d_nsectors = 63;
lp->d_ntracks = 255;
lp->d_secperunit = ms / lp->d_secsize;
}
/* /*
* Get disk slice, partition, and geometry information. * Get disk slice, partition, and geometry information.
*/ */
@ -819,8 +853,10 @@ getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
struct bpb *bpb) struct bpb *bpb)
{ {
struct disklabel *lp, dlp; struct disklabel *lp, dlp;
off_t hs = 0;
#ifndef MAKEFS
off_t ms;
struct fd_type type; struct fd_type type;
off_t ms, hs = 0;
lp = NULL; lp = NULL;
@ -832,16 +868,8 @@ getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
/* Maybe it's a floppy drive */ /* Maybe it's a floppy drive */
if (lp == NULL) { if (lp == NULL) {
if (ioctl(fd, DIOCGMEDIASIZE, &ms) == -1) { if (ioctl(fd, DIOCGMEDIASIZE, &ms) == -1) {
struct stat st;
if (fstat(fd, &st))
err(1, "cannot get disk size");
/* create a fake geometry for a file image */ /* create a fake geometry for a file image */
ms = st.st_size; compute_geometry_from_file(fd, fname, &dlp);
dlp.d_secsize = 512;
dlp.d_nsectors = 63;
dlp.d_ntracks = 255;
dlp.d_secperunit = ms / dlp.d_secsize;
lp = &dlp; lp = &dlp;
} else if (ioctl(fd, FD_GTYPE, &type) != -1) { } else if (ioctl(fd, FD_GTYPE, &type) != -1) {
dlp.d_secsize = 128 << type.secsize; dlp.d_secsize = 128 << type.secsize;
@ -881,6 +909,11 @@ getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
hs = (ms / dlp.d_secsize) - dlp.d_secperunit; hs = (ms / dlp.d_secsize) - dlp.d_secperunit;
lp = &dlp; lp = &dlp;
} }
#else
/* In the makefs case we only support image files: */
compute_geometry_from_file(fd, fname, &dlp);
lp = &dlp;
#endif
if (bpb->bpbBytesPerSec == 0) { if (bpb->bpbBytesPerSec == 0) {
if (ckgeom(fname, lp->d_secsize, "bytes/sector") == -1) if (ckgeom(fname, lp->d_secsize, "bytes/sector") == -1)

View File

@ -79,11 +79,10 @@ LIB32CPUFLAGS= -target mips-unknown-freebsd13.0
.endif .endif
LIB32CPUFLAGS+= -mabi=32 LIB32CPUFLAGS+= -mabi=32
LIB32_MACHINE= mips LIB32_MACHINE= mips
LIB32_MACHINE_ARCH:= ${COMPAT_ARCH:S/64//}
.if ${COMPAT_ARCH:Mmips64el*} != "" .if ${COMPAT_ARCH:Mmips64el*} != ""
LIB32_MACHINE_ARCH= mipsel
_EMULATION= elf32ltsmip_fbsd _EMULATION= elf32ltsmip_fbsd
.else .else
LIB32_MACHINE_ARCH= mips
_EMULATION= elf32btsmip_fbsd _EMULATION= elf32btsmip_fbsd
.endif .endif
LIB32WMAKEFLAGS= LD="${XLD} -m ${_EMULATION}" LIB32WMAKEFLAGS= LD="${XLD} -m ${_EMULATION}"

View File

@ -50,12 +50,9 @@ ARCH_FLAGS+=-mabi=${MIPS_ABI}
EXTRA_FLAGS=-fno-pic -mno-abicalls -G0 -DKERNLOADADDR=${KERNLOADADDR} EXTRA_FLAGS=-fno-pic -mno-abicalls -G0 -DKERNLOADADDR=${KERNLOADADDR}
EXTRA_FLAGS+=-${MIPS_ENDIAN} EXTRA_FLAGS+=-${MIPS_ENDIAN}
HACK_EXTRA_FLAGS=-shared
# We add the -fno-pic flag to kernels because otherwise performance # We add the -fno-pic flag to kernels because otherwise performance
# is extremely poor, as well as -mno-abicalls to force no ABI usage. # is extremely poor, as well as -mno-abicalls to force no ABI usage.
CFLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS) CFLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS)
HACK_EXTRA_FLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS)
TRAMP_ARCH_FLAGS?=$(ARCH_FLAGS) TRAMP_ARCH_FLAGS?=$(ARCH_FLAGS)
TRAMP_EXTRA_FLAGS=${EXTRA_FLAGS} ${TRAMP_ARCH_FLAGS} TRAMP_EXTRA_FLAGS=${EXTRA_FLAGS} ${TRAMP_ARCH_FLAGS}
# Kernel code is always compiled with soft-float on MIPS # Kernel code is always compiled with soft-float on MIPS

View File

@ -39,7 +39,6 @@ INCLUDES+= -I$S/contrib/libfdt
# Force __SPE__, since the builtin will be removed later with -mno-spe # Force __SPE__, since the builtin will be removed later with -mno-spe
CFLAGS.gcc+= -mabi=spe -D__SPE__ CFLAGS.gcc+= -mabi=spe -D__SPE__
CFLAGS.clang+= -mspe -D__SPE__ -m32 CFLAGS.clang+= -mspe -D__SPE__ -m32
HACK_EXTRA_FLAGS= -shared -m32 -mspe -D__SPE__
.endif .endif
CFLAGS+= -msoft-float CFLAGS+= -msoft-float
CFLAGS.gcc+= -Wa,-many CFLAGS.gcc+= -Wa,-many

View File

@ -226,10 +226,9 @@ kernel-clean:
# This is a hack. BFD "optimizes" away dynamic mode if there are no # This is a hack. BFD "optimizes" away dynamic mode if there are no
# dynamic references. We could probably do a '-Bforcedynamic' mode like # dynamic references. We could probably do a '-Bforcedynamic' mode like
# in the a.out ld. For now, this works. # in the a.out ld. For now, this works.
HACK_EXTRA_FLAGS?= -shared
hack.pico: Makefile hack.pico: Makefile
:> hack.c :> hack.c
${CC} ${HACK_EXTRA_FLAGS} -nostdlib hack.c -o hack.pico ${CC} -shared ${CFLAGS} -nostdlib hack.c -o hack.pico
rm -f hack.c rm -f hack.c
offset.inc: $S/kern/genoffset.sh genoffset.o offset.inc: $S/kern/genoffset.sh genoffset.o

View File

@ -1908,13 +1908,14 @@ mrsas_track_scsiio(struct mrsas_softc *sc, target_id_t tgt_id, u_int32_t bus_id)
for (i = 0 ; i < sc->max_fw_cmds; i++) { for (i = 0 ; i < sc->max_fw_cmds; i++) {
mpt_cmd = sc->mpt_cmd_list[i]; mpt_cmd = sc->mpt_cmd_list[i];
/* /*
* Check if the target_id and bus_id is same as the timeout IO * Check if the target_id and bus_id is same as the timeout IO
*/ */
if (mpt_cmd->ccb_ptr) { if (mpt_cmd->ccb_ptr) {
/* bus_id = 1 denotes a VD */ /* bus_id = 1 denotes a VD */
if (bus_id == 1) if (bus_id == 1)
tgt_id = (mpt_cmd->ccb_ptr->ccb_h.target_id - (MRSAS_MAX_PD - 1)); tgt_id =
(mpt_cmd->ccb_ptr->ccb_h.target_id - (MRSAS_MAX_PD - 1));
if (mpt_cmd->ccb_ptr->cpi.bus_id == bus_id && if (mpt_cmd->ccb_ptr->cpi.bus_id == bus_id &&
mpt_cmd->ccb_ptr->ccb_h.target_id == tgt_id) { mpt_cmd->ccb_ptr->ccb_h.target_id == tgt_id) {

View File

@ -3374,6 +3374,7 @@ msk_txeof(struct msk_if_softc *sc_if, int idx)
static void static void
msk_tick(void *xsc_if) msk_tick(void *xsc_if)
{ {
struct epoch_tracker et;
struct msk_if_softc *sc_if; struct msk_if_softc *sc_if;
struct mii_data *mii; struct mii_data *mii;
@ -3386,7 +3387,9 @@ msk_tick(void *xsc_if)
mii_tick(mii); mii_tick(mii);
if ((sc_if->msk_flags & MSK_FLAG_LINK) == 0) if ((sc_if->msk_flags & MSK_FLAG_LINK) == 0)
msk_miibus_statchg(sc_if->msk_if_dev); msk_miibus_statchg(sc_if->msk_if_dev);
NET_EPOCH_ENTER(et);
msk_handle_events(sc_if->msk_softc); msk_handle_events(sc_if->msk_softc);
NET_EPOCH_EXIT(et);
msk_watchdog(sc_if); msk_watchdog(sc_if);
callout_reset(&sc_if->msk_tick_ch, hz, msk_tick, sc_if); callout_reset(&sc_if->msk_tick_ch, hz, msk_tick, sc_if);
} }

View File

@ -1523,11 +1523,12 @@ static int
netmap_mem_unmap(struct netmap_obj_pool *p, struct netmap_adapter *na) netmap_mem_unmap(struct netmap_obj_pool *p, struct netmap_adapter *na)
{ {
int i, lim = p->objtotal; int i, lim = p->objtotal;
struct netmap_lut *lut = &na->na_lut; struct netmap_lut *lut;
if (na == NULL || na->pdev == NULL) if (na == NULL || na->pdev == NULL)
return 0; return 0;
lut = &na->na_lut;
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
/* On FreeBSD mapping and unmapping is performed by the txsync /* On FreeBSD mapping and unmapping is performed by the txsync
* and rxsync routine, packet by packet. */ * and rxsync routine, packet by packet. */

View File

@ -1257,11 +1257,12 @@ emu_intr(void *data)
#endif #endif
} }
if (stat & EMU_IPR_MIDIRECVBUFE) if (stat & EMU_IPR_MIDIRECVBUFE) {
if (sc->mpu_intr) { if (sc->mpu_intr) {
(sc->mpu_intr)(sc->mpu); (sc->mpu_intr)(sc->mpu);
ack |= EMU_IPR_MIDIRECVBUFE | EMU_IPR_MIDITRANSBUFE; ack |= EMU_IPR_MIDIRECVBUFE | EMU_IPR_MIDITRANSBUFE;
} }
}
if (stat & ~ack) if (stat & ~ack)
device_printf(sc->dev, "dodgy irq: %x (harmless)\n", device_printf(sc->dev, "dodgy irq: %x (harmless)\n",
stat & ~ack); stat & ~ack);

View File

@ -263,11 +263,12 @@ emu_dspmixer_uninit(struct snd_mixer *m)
/* drop submixer for AC97 codec */ /* drop submixer for AC97 codec */
sc = mix_getdevinfo(m); sc = mix_getdevinfo(m);
if (sc->sm != NULL) if (sc->sm != NULL) {
err = mixer_delete(sc->sm); err = mixer_delete(sc->sm);
if (err) if (err)
return (err); return (err);
sc->sm = NULL; sc->sm = NULL;
}
return (0); return (0);
} }

View File

@ -56,8 +56,10 @@
#if defined (_KERNEL) || defined(MAKEFS) #if defined (_KERNEL) || defined(MAKEFS)
#include <sys/types.h> #include <sys/types.h>
#ifndef MAKEFS
#include <sys/lock.h> #include <sys/lock.h>
#include <sys/lockmgr.h> #include <sys/lockmgr.h>
#endif
#include <sys/tree.h> #include <sys/tree.h>
#ifdef MALLOC_DECLARE #ifdef MALLOC_DECLARE
@ -110,7 +112,9 @@ struct msdosfsmount {
void *pm_w2u; /* Unicode->Local iconv handle */ void *pm_w2u; /* Unicode->Local iconv handle */
void *pm_u2d; /* Unicode->DOS iconv handle */ void *pm_u2d; /* Unicode->DOS iconv handle */
void *pm_d2u; /* DOS->Local iconv handle */ void *pm_d2u; /* DOS->Local iconv handle */
#ifndef MAKEFS
struct lock pm_fatlock; /* lockmgr protecting allocations */ struct lock pm_fatlock; /* lockmgr protecting allocations */
#endif
}; };
/* /*

View File

@ -1554,7 +1554,8 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
tvp = NULL; tvp = NULL;
else if (vp == NULL && cansleep != 0) { else if (vp == NULL && cansleep != 0) {
tvp = nfsvno_getvp(&lfp->lf_fh); tvp = nfsvno_getvp(&lfp->lf_fh);
NFSVOPUNLOCK(tvp); if (tvp != NULL)
NFSVOPUNLOCK(tvp);
} else } else
tvp = vp; tvp = vp;
gottvp = 1; gottvp = 1;

View File

@ -1134,8 +1134,11 @@ g_std_done(struct bio *bp)
bp2->bio_completed += bp->bio_completed; bp2->bio_completed += bp->bio_completed;
g_destroy_bio(bp); g_destroy_bio(bp);
bp2->bio_inbed++; bp2->bio_inbed++;
if (bp2->bio_children == bp2->bio_inbed) if (bp2->bio_children == bp2->bio_inbed) {
if (bp2->bio_cmd == BIO_SPEEDUP)
bp2->bio_completed = bp2->bio_length;
g_io_deliver(bp2, bp2->bio_error); g_io_deliver(bp2, bp2->bio_error);
}
} }
/* XXX: maybe this is only g_slice_spoiled */ /* XXX: maybe this is only g_slice_spoiled */

View File

@ -298,6 +298,8 @@ g_stripe_done(struct bio *bp)
mtx_unlock(&sc->sc_lock); mtx_unlock(&sc->sc_lock);
if (pbp->bio_driver1 != NULL) if (pbp->bio_driver1 != NULL)
uma_zfree(g_stripe_zone, pbp->bio_driver1); uma_zfree(g_stripe_zone, pbp->bio_driver1);
if (bp->bio_cmd == BIO_SPEEDUP)
pbp->bio_completed = pbp->bio_length;
g_io_deliver(pbp, pbp->bio_error); g_io_deliver(pbp, pbp->bio_error);
} else } else
mtx_unlock(&sc->sc_lock); mtx_unlock(&sc->sc_lock);

View File

@ -1450,20 +1450,7 @@ vop_sigdefer(struct vop_vector *vop, struct vop_generic_args *a)
vop_bypass_t *bp; vop_bypass_t *bp;
int prev_stops, rc; int prev_stops, rc;
for (; vop != NULL; vop = vop->vop_default) { bp = bp_by_off(vop, a);
bp = bp_by_off(vop, a);
if (bp != NULL)
break;
/*
* Bypass is not really supported. It is done for
* fallback to unimplemented vops in the default
* vector.
*/
bp = vop->vop_bypass;
if (bp != NULL)
break;
}
MPASS(bp != NULL); MPASS(bp != NULL);
prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT); prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);

View File

@ -2911,7 +2911,8 @@ vget_finish(struct vnode *vp, int flags, enum vgetstate vs)
__func__)); __func__));
} }
if ((error = vn_lock(vp, flags)) != 0) { error = vn_lock(vp, flags);
if (__predict_false(error != 0)) {
if (vs == VGET_USECOUNT) if (vs == VGET_USECOUNT)
vrele(vp); vrele(vp);
else else
@ -3323,10 +3324,10 @@ vdbatch_process(struct vdbatch *vd)
vp->v_dbatchcpu = NOCPU; vp->v_dbatchcpu = NOCPU;
} }
mtx_unlock(&vnode_list_mtx); mtx_unlock(&vnode_list_mtx);
critical_exit();
vd->freevnodes = 0; vd->freevnodes = 0;
bzero(vd->tab, sizeof(vd->tab)); bzero(vd->tab, sizeof(vd->tab));
vd->index = 0; vd->index = 0;
critical_exit();
} }
static void static void
@ -6367,6 +6368,9 @@ __mnt_vnode_first_lazy(struct vnode **mvp, struct mount *mp, mnt_lazy_cb_t *cb,
{ {
struct vnode *vp; struct vnode *vp;
if (TAILQ_EMPTY(&mp->mnt_lazyvnodelist))
return (NULL);
*mvp = vn_alloc_marker(mp); *mvp = vn_alloc_marker(mp);
MNT_ILOCK(mp); MNT_ILOCK(mp);
MNT_REF(mp); MNT_REF(mp);

View File

@ -371,9 +371,11 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
case IPVERSION: case IPVERSION:
family = AF_INET; family = AF_INET;
break; break;
#ifdef INET6
case IPV6_VERSION >> 4: case IPV6_VERSION >> 4:
family = AF_INET6; family = AF_INET6;
break; break;
#endif
default: default:
m_freem(m); m_freem(m);
return (EAFNOSUPPORT); return (EAFNOSUPPORT);

View File

@ -335,8 +335,12 @@ struct { \
RB_COLOR(red, field) = RB_RED; \ RB_COLOR(red, field) = RB_RED; \
} while (/*CONSTCOND*/ 0) } while (/*CONSTCOND*/ 0)
/*
* Something to be invoked in a loop at the root of every modified subtree,
* from the bottom up to the root, to update augmented node data.
*/
#ifndef RB_AUGMENT #ifndef RB_AUGMENT
#define RB_AUGMENT(x) do {} while (0) #define RB_AUGMENT(x) break
#endif #endif
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
@ -344,7 +348,6 @@ struct { \
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
} \ } \
RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
@ -354,9 +357,7 @@ struct { \
(head)->rbh_root = (tmp); \ (head)->rbh_root = (tmp); \
RB_LEFT(tmp, field) = (elm); \ RB_LEFT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \ RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \ RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field))) \
RB_AUGMENT(RB_PARENT(tmp, field)); \
} while (/*CONSTCOND*/ 0) } while (/*CONSTCOND*/ 0)
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
@ -364,7 +365,6 @@ struct { \
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
} \ } \
RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
@ -374,9 +374,7 @@ struct { \
(head)->rbh_root = (tmp); \ (head)->rbh_root = (tmp); \
RB_RIGHT(tmp, field) = (elm); \ RB_RIGHT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \ RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \ RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field))) \
RB_AUGMENT(RB_PARENT(tmp, field)); \
} while (/*CONSTCOND*/ 0) } while (/*CONSTCOND*/ 0)
/* Generates prototypes and inline functions */ /* Generates prototypes and inline functions */
@ -571,62 +569,49 @@ name##_RB_REMOVE(struct name *head, struct type *elm) \
else if (RB_RIGHT(elm, field) == NULL) \ else if (RB_RIGHT(elm, field) == NULL) \
child = RB_LEFT(elm, field); \ child = RB_LEFT(elm, field); \
else { \ else { \
struct type *left; \ elm = RB_RIGHT(old, field); \
elm = RB_RIGHT(elm, field); \ if ((child = RB_LEFT(elm, field)) == NULL) { \
while ((left = RB_LEFT(elm, field)) != NULL) \ child = RB_RIGHT(elm, field); \
elm = left; \ RB_RIGHT(old, field) = child; \
child = RB_RIGHT(elm, field); \ RB_PARENT(elm, field) = elm; \
parent = RB_PARENT(elm, field); \ } else { \
color = RB_COLOR(elm, field); \ do \
if (child) \ elm = child; \
RB_PARENT(child, field) = parent; \ while ((child = RB_LEFT(elm, field)) != NULL); \
if (parent) { \ child = RB_RIGHT(elm, field); \
if (RB_LEFT(parent, field) == elm) \ RB_PARENT(RB_RIGHT(old, field), field) = elm; \
RB_LEFT(parent, field) = child; \ } \
RB_PARENT(RB_LEFT(old, field), field) = elm; \
parent = RB_PARENT(old, field); \
if (parent != NULL) { \
if (RB_LEFT(parent, field) == old) \
RB_LEFT(parent, field) = elm; \
else \ else \
RB_RIGHT(parent, field) = child; \ RB_RIGHT(parent, field) = elm; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = child; \
if (RB_PARENT(elm, field) == old) \
parent = elm; \
(elm)->field = (old)->field; \
if (RB_PARENT(old, field)) { \
if (RB_LEFT(RB_PARENT(old, field), field) == old)\
RB_LEFT(RB_PARENT(old, field), field) = elm;\
else \
RB_RIGHT(RB_PARENT(old, field), field) = elm;\
RB_AUGMENT(RB_PARENT(old, field)); \
} else \ } else \
RB_ROOT(head) = elm; \ RB_ROOT(head) = elm; \
RB_PARENT(RB_LEFT(old, field), field) = elm; \
if (RB_RIGHT(old, field)) \
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
if (parent) { \
left = parent; \
do { \
RB_AUGMENT(left); \
} while ((left = RB_PARENT(left, field)) != NULL); \
} \
goto color; \
} \ } \
parent = RB_PARENT(elm, field); \ parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \ color = RB_COLOR(elm, field); \
if (child) \ if (child != NULL) \
RB_PARENT(child, field) = parent; \ RB_PARENT(child, field) = parent; \
if (parent) { \ if (parent != NULL) { \
if (RB_LEFT(parent, field) == elm) \ if (RB_LEFT(parent, field) == elm) \
RB_LEFT(parent, field) = child; \ RB_LEFT(parent, field) = child; \
else \ else \
RB_RIGHT(parent, field) = child; \ RB_RIGHT(parent, field) = child; \
RB_AUGMENT(parent); \
} else \ } else \
RB_ROOT(head) = child; \ RB_ROOT(head) = child; \
color: \ if (elm != old) \
(elm)->field = (old)->field; \
if (color == RB_BLACK) \ if (color == RB_BLACK) \
name##_RB_REMOVE_COLOR(head, parent, child); \ name##_RB_REMOVE_COLOR(head, parent, child); \
while (parent != NULL) { \
RB_AUGMENT(parent); \
parent = RB_PARENT(parent, field); \
} \
return (old); \ return (old); \
} \ }
#define RB_GENERATE_INSERT(name, type, field, cmp, attr) \ #define RB_GENERATE_INSERT(name, type, field, cmp, attr) \
/* Inserts a node into the RB tree */ \ /* Inserts a node into the RB tree */ \
@ -653,10 +638,13 @@ name##_RB_INSERT(struct name *head, struct type *elm) \
RB_LEFT(parent, field) = elm; \ RB_LEFT(parent, field) = elm; \
else \ else \
RB_RIGHT(parent, field) = elm; \ RB_RIGHT(parent, field) = elm; \
RB_AUGMENT(parent); \
} else \ } else \
RB_ROOT(head) = elm; \ RB_ROOT(head) = elm; \
name##_RB_INSERT_COLOR(head, elm); \ name##_RB_INSERT_COLOR(head, elm); \
while (elm != NULL) { \
RB_AUGMENT(elm); \
elm = RB_PARENT(elm, field); \
} \
return (NULL); \ return (NULL); \
} }

View File

@ -367,14 +367,11 @@ while ((getline < srcfile) > 0) {
add_pre(name); add_pre(name);
for (i = 0; i < numargs; ++i) for (i = 0; i < numargs; ++i)
add_debug_code(name, args[i], "Entry", "\t"); add_debug_code(name, args[i], "Entry", "\t");
printc("\tif (__predict_true(!SDT_PROBES_ENABLED() && vop->"name" != NULL)) {"); printc("\tif (!SDT_PROBES_ENABLED()) {");
printc("\t\trc = vop->"name"(a);") printc("\t\trc = vop->"name"(a);")
printc("\t} else {") printc("\t} else {")
printc("\t\tSDT_PROBE2(vfs, vop, " name ", entry, a->a_" args[0] ", a);"); printc("\t\tSDT_PROBE2(vfs, vop, " name ", entry, a->a_" args[0] ", a);");
printc("\t\tif (vop->"name" != NULL)") printc("\t\trc = vop->"name"(a);")
printc("\t\t\trc = vop->"name"(a);")
printc("\t\telse")
printc("\t\t\trc = vop->vop_bypass(&a->a_gen);")
printc("\t\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);"); printc("\t\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);");
printc("\t}") printc("\t}")
printc("\tif (rc == 0) {"); printc("\tif (rc == 0) {");
@ -450,6 +447,11 @@ if (cfile) {
printc("\tif (vop != NULL)"); printc("\tif (vop != NULL)");
printc("\t\torig_vop->vop_bypass = vop->vop_bypass;"); printc("\t\torig_vop->vop_bypass = vop->vop_bypass;");
printc(""); printc("");
for (name in funcarr) {
printc("\tif (orig_vop->"name" == NULL)");
printc("\t\torig_vop->"name" = (void *)orig_vop->vop_bypass;");
}
printc("");
printc("\torig_vop->registered = true;"); printc("\torig_vop->registered = true;");
printc("}") printc("}")
} }

View File

@ -1787,6 +1787,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
* still zero, it will be unlinked and returned to the free * still zero, it will be unlinked and returned to the free
* list by vput(). * list by vput().
*/ */
vgone(vp);
vput(vp); vput(vp);
*vpp = NULL; *vpp = NULL;
return (error); return (error);
@ -1797,6 +1798,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK); ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK);
if ((error = ffs_load_inode(bp, ip, fs, ino)) != 0) { if ((error = ffs_load_inode(bp, ip, fs, ino)) != 0) {
bqrelse(bp); bqrelse(bp);
vgone(vp);
vput(vp); vput(vp);
*vpp = NULL; *vpp = NULL;
return (error); return (error);
@ -1814,6 +1816,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
error = ufs_vinit(mp, I_IS_UFS1(ip) ? &ffs_fifoops1 : &ffs_fifoops2, error = ufs_vinit(mp, I_IS_UFS1(ip) ? &ffs_fifoops1 : &ffs_fifoops2,
&vp); &vp);
if (error) { if (error) {
vgone(vp);
vput(vp); vput(vp);
*vpp = NULL; *vpp = NULL;
return (error); return (error);
@ -1849,6 +1852,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
error = mac_vnode_associate_extattr(mp, vp); error = mac_vnode_associate_extattr(mp, vp);
if (error) { if (error) {
/* ufs_inactive will release ip->i_devvp ref. */ /* ufs_inactive will release ip->i_devvp ref. */
vgone(vp);
vput(vp); vput(vp);
*vpp = NULL; *vpp = NULL;
return (error); return (error);

View File

@ -1839,6 +1839,7 @@ ufs_mkdir(ap)
if (DOINGSOFTDEP(tvp)) if (DOINGSOFTDEP(tvp))
softdep_revert_link(dp, ip); softdep_revert_link(dp, ip);
UFS_VFREE(tvp, ip->i_number, dmode); UFS_VFREE(tvp, ip->i_number, dmode);
vgone(tvp);
vput(tvp); vput(tvp);
return (error); return (error);
} }
@ -1853,6 +1854,7 @@ ufs_mkdir(ap)
if (DOINGSOFTDEP(tvp)) if (DOINGSOFTDEP(tvp))
softdep_revert_link(dp, ip); softdep_revert_link(dp, ip);
UFS_VFREE(tvp, ip->i_number, dmode); UFS_VFREE(tvp, ip->i_number, dmode);
vgone(tvp);
vput(tvp); vput(tvp);
return (error); return (error);
} }
@ -1980,7 +1982,7 @@ ufs_mkdir(ap)
UFS_INODE_SET_FLAG(ip, IN_CHANGE); UFS_INODE_SET_FLAG(ip, IN_CHANGE);
if (DOINGSOFTDEP(tvp)) if (DOINGSOFTDEP(tvp))
softdep_revert_mkdir(dp, ip); softdep_revert_mkdir(dp, ip);
vgone(tvp);
vput(tvp); vput(tvp);
} }
out: out:
@ -2607,6 +2609,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
if (DOINGSOFTDEP(tvp)) if (DOINGSOFTDEP(tvp))
softdep_revert_link(pdir, ip); softdep_revert_link(pdir, ip);
UFS_VFREE(tvp, ip->i_number, mode); UFS_VFREE(tvp, ip->i_number, mode);
vgone(tvp);
vput(tvp); vput(tvp);
return (error); return (error);
} }
@ -2621,6 +2624,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
if (DOINGSOFTDEP(tvp)) if (DOINGSOFTDEP(tvp))
softdep_revert_link(pdir, ip); softdep_revert_link(pdir, ip);
UFS_VFREE(tvp, ip->i_number, mode); UFS_VFREE(tvp, ip->i_number, mode);
vgone(tvp);
vput(tvp); vput(tvp);
return (error); return (error);
} }
@ -2691,6 +2695,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
UFS_INODE_SET_FLAG(ip, IN_CHANGE); UFS_INODE_SET_FLAG(ip, IN_CHANGE);
if (DOINGSOFTDEP(tvp)) if (DOINGSOFTDEP(tvp))
softdep_revert_create(VTOI(dvp), ip); softdep_revert_create(VTOI(dvp), ip);
vgone(tvp);
vput(tvp); vput(tvp);
return (error); return (error);
} }

View File

@ -173,8 +173,12 @@ hwpstate_goto_pstate(device_t dev, int id)
/* get the current pstate limit */ /* get the current pstate limit */
msr = rdmsr(MSR_AMD_10H_11H_LIMIT); msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
limit = AMD_10H_11H_GET_PSTATE_LIMIT(msr); limit = AMD_10H_11H_GET_PSTATE_LIMIT(msr);
if (limit > id) if (limit > id) {
HWPSTATE_DEBUG(dev,
"Restricting requested P%d to P%d due to HW limit\n", id,
limit);
id = limit; id = limit;
}
cpu = curcpu; cpu = curcpu;
HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, cpu); HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, cpu);

View File

@ -47,7 +47,8 @@ struct dmar_qi_genseq {
struct dmar_map_entry { struct dmar_map_entry {
dmar_gaddr_t start; dmar_gaddr_t start;
dmar_gaddr_t end; dmar_gaddr_t end;
dmar_gaddr_t free_after; /* Free space after the entry */ dmar_gaddr_t first; /* Least start in subtree */
dmar_gaddr_t last; /* Greatest end in subtree */
dmar_gaddr_t free_down; /* Max free space below the dmar_gaddr_t free_down; /* Max free space below the
current R/B tree node */ current R/B tree node */
u_int flags; u_int flags;

View File

@ -1112,9 +1112,9 @@ dmar_print_domain_entry(const struct dmar_map_entry *entry)
struct dmar_map_entry *l, *r; struct dmar_map_entry *l, *r;
db_printf( db_printf(
" start %jx end %jx free_after %jx free_down %jx flags %x ", " start %jx end %jx first %jx last %jx free_down %jx flags %x ",
entry->start, entry->end, entry->free_after, entry->free_down, entry->start, entry->end, entry->first, entry->last,
entry->flags); entry->free_down, entry->flags);
db_printf("left "); db_printf("left ");
l = RB_LEFT(entry, rb_entry); l = RB_LEFT(entry, rb_entry);
if (l == NULL) if (l == NULL)

View File

@ -139,71 +139,52 @@ dmar_gas_cmp_entries(struct dmar_map_entry *a, struct dmar_map_entry *b)
static void static void
dmar_gas_augment_entry(struct dmar_map_entry *entry) dmar_gas_augment_entry(struct dmar_map_entry *entry)
{ {
struct dmar_map_entry *l, *r; struct dmar_map_entry *child;
dmar_gaddr_t free_down;
for (; entry != NULL; entry = RB_PARENT(entry, rb_entry)) { free_down = 0;
l = RB_LEFT(entry, rb_entry); if ((child = RB_LEFT(entry, rb_entry)) != NULL) {
r = RB_RIGHT(entry, rb_entry); free_down = MAX(free_down, child->free_down);
if (l == NULL && r == NULL) { free_down = MAX(free_down, entry->start - child->last);
entry->free_down = entry->free_after; entry->first = child->first;
} else if (l == NULL && r != NULL) { } else
entry->free_down = MAX(entry->free_after, r->free_down); entry->first = entry->start;
} else if (/*l != NULL && */ r == NULL) {
entry->free_down = MAX(entry->free_after, l->free_down); if ((child = RB_RIGHT(entry, rb_entry)) != NULL) {
} else /* if (l != NULL && r != NULL) */ { free_down = MAX(free_down, child->free_down);
entry->free_down = MAX(entry->free_after, l->free_down); free_down = MAX(free_down, child->first - entry->end);
entry->free_down = MAX(entry->free_down, r->free_down); entry->last = child->last;
} } else
} entry->last = entry->end;
entry->free_down = free_down;
} }
RB_GENERATE(dmar_gas_entries_tree, dmar_map_entry, rb_entry, RB_GENERATE(dmar_gas_entries_tree, dmar_map_entry, rb_entry,
dmar_gas_cmp_entries); dmar_gas_cmp_entries);
static void
dmar_gas_fix_free(struct dmar_domain *domain, struct dmar_map_entry *entry)
{
struct dmar_map_entry *next;
next = RB_NEXT(dmar_gas_entries_tree, &domain->rb_root, entry);
entry->free_after = (next != NULL ? next->start : domain->end) -
entry->end;
dmar_gas_augment_entry(entry);
}
#ifdef INVARIANTS #ifdef INVARIANTS
static void static void
dmar_gas_check_free(struct dmar_domain *domain) dmar_gas_check_free(struct dmar_domain *domain)
{ {
struct dmar_map_entry *entry, *next, *l, *r; struct dmar_map_entry *entry, *l, *r;
dmar_gaddr_t v; dmar_gaddr_t v;
RB_FOREACH(entry, dmar_gas_entries_tree, &domain->rb_root) { RB_FOREACH(entry, dmar_gas_entries_tree, &domain->rb_root) {
KASSERT(domain == entry->domain, KASSERT(domain == entry->domain,
("mismatched free domain %p entry %p entry->domain %p", ("mismatched free domain %p entry %p entry->domain %p",
domain, entry, entry->domain)); domain, entry, entry->domain));
next = RB_NEXT(dmar_gas_entries_tree, &domain->rb_root, entry);
if (next == NULL) {
MPASS(entry->free_after == domain->end - entry->end);
} else {
MPASS(entry->free_after = next->start - entry->end);
MPASS(entry->end <= next->start);
}
l = RB_LEFT(entry, rb_entry); l = RB_LEFT(entry, rb_entry);
r = RB_RIGHT(entry, rb_entry); r = RB_RIGHT(entry, rb_entry);
if (l == NULL && r == NULL) { v = 0;
MPASS(entry->free_down == entry->free_after); if (l != NULL) {
} else if (l == NULL && r != NULL) { v = MAX(v, l->free_down);
MPASS(entry->free_down = MAX(entry->free_after, v = MAX(v, entry->start - l->last);
r->free_down));
} else if (r == NULL) {
MPASS(entry->free_down = MAX(entry->free_after,
l->free_down));
} else {
v = MAX(entry->free_after, l->free_down);
v = MAX(v, r->free_down);
MPASS(entry->free_down == v);
} }
if (r != NULL) {
v = MAX(v, r->free_down);
v = MAX(v, r->first - entry->end);
}
MPASS(entry->free_down == v);
} }
} }
#endif #endif
@ -211,25 +192,17 @@ dmar_gas_check_free(struct dmar_domain *domain)
static bool static bool
dmar_gas_rb_insert(struct dmar_domain *domain, struct dmar_map_entry *entry) dmar_gas_rb_insert(struct dmar_domain *domain, struct dmar_map_entry *entry)
{ {
struct dmar_map_entry *prev, *found; struct dmar_map_entry *found;
found = RB_INSERT(dmar_gas_entries_tree, &domain->rb_root, entry); found = RB_INSERT(dmar_gas_entries_tree, &domain->rb_root, entry);
dmar_gas_fix_free(domain, entry);
prev = RB_PREV(dmar_gas_entries_tree, &domain->rb_root, entry);
if (prev != NULL)
dmar_gas_fix_free(domain, prev);
return (found == NULL); return (found == NULL);
} }
static void static void
dmar_gas_rb_remove(struct dmar_domain *domain, struct dmar_map_entry *entry) dmar_gas_rb_remove(struct dmar_domain *domain, struct dmar_map_entry *entry)
{ {
struct dmar_map_entry *prev;
prev = RB_PREV(dmar_gas_entries_tree, &domain->rb_root, entry);
RB_REMOVE(dmar_gas_entries_tree, &domain->rb_root, entry); RB_REMOVE(dmar_gas_entries_tree, &domain->rb_root, entry);
if (prev != NULL)
dmar_gas_fix_free(domain, prev);
} }
void void
@ -246,13 +219,11 @@ dmar_gas_init_domain(struct dmar_domain *domain)
begin->start = 0; begin->start = 0;
begin->end = DMAR_PAGE_SIZE; begin->end = DMAR_PAGE_SIZE;
begin->free_after = domain->end - begin->end;
begin->flags = DMAR_MAP_ENTRY_PLACE | DMAR_MAP_ENTRY_UNMAPPED; begin->flags = DMAR_MAP_ENTRY_PLACE | DMAR_MAP_ENTRY_UNMAPPED;
dmar_gas_rb_insert(domain, begin); dmar_gas_rb_insert(domain, begin);
end->start = domain->end; end->start = domain->end;
end->end = domain->end; end->end = domain->end;
end->free_after = 0;
end->flags = DMAR_MAP_ENTRY_PLACE | DMAR_MAP_ENTRY_UNMAPPED; end->flags = DMAR_MAP_ENTRY_PLACE | DMAR_MAP_ENTRY_UNMAPPED;
dmar_gas_rb_insert(domain, end); dmar_gas_rb_insert(domain, end);
@ -281,7 +252,6 @@ dmar_gas_fini_domain(struct dmar_domain *domain)
entry = RB_MAX(dmar_gas_entries_tree, &domain->rb_root); entry = RB_MAX(dmar_gas_entries_tree, &domain->rb_root);
KASSERT(entry->start == domain->end, ("end entry start %p", domain)); KASSERT(entry->start == domain->end, ("end entry start %p", domain));
KASSERT(entry->end == domain->end, ("end entry end %p", domain)); KASSERT(entry->end == domain->end, ("end entry end %p", domain));
KASSERT(entry->free_after == 0, ("end entry free_after %p", domain));
KASSERT(entry->flags == DMAR_MAP_ENTRY_PLACE, KASSERT(entry->flags == DMAR_MAP_ENTRY_PLACE,
("end entry flags %p", domain)); ("end entry flags %p", domain));
RB_REMOVE(dmar_gas_entries_tree, &domain->rb_root, entry); RB_REMOVE(dmar_gas_entries_tree, &domain->rb_root, entry);
@ -305,19 +275,26 @@ struct dmar_gas_match_args {
struct dmar_map_entry *entry; struct dmar_map_entry *entry;
}; };
/*
* The interval [beg, end) is a free interval between two dmar_map_entries.
* maxaddr is an upper bound on addresses that can be allocated. Try to
* allocate space in the free interval, subject to the conditions expressed
* by a, and return 'true' if and only if the allocation attempt succeeds.
*/
static bool static bool
dmar_gas_match_one(struct dmar_gas_match_args *a, struct dmar_map_entry *prev, dmar_gas_match_one(struct dmar_gas_match_args *a, dmar_gaddr_t beg,
dmar_gaddr_t end) dmar_gaddr_t end, dmar_gaddr_t maxaddr)
{ {
dmar_gaddr_t bs, start; dmar_gaddr_t bs, start;
if (a->entry->start + a->size > end) a->entry->start = roundup2(beg + DMAR_PAGE_SIZE,
a->common->alignment);
if (a->entry->start + a->size > maxaddr)
return (false); return (false);
/* DMAR_PAGE_SIZE to create gap after new entry. */ /* DMAR_PAGE_SIZE to create gap after new entry. */
if (a->entry->start < prev->end + DMAR_PAGE_SIZE || if (a->entry->start < beg + DMAR_PAGE_SIZE ||
a->entry->start + a->size + a->offset + DMAR_PAGE_SIZE > a->entry->start + a->size + a->offset + DMAR_PAGE_SIZE > end)
prev->end + prev->free_after)
return (false); return (false);
/* No boundary crossing. */ /* No boundary crossing. */
@ -328,15 +305,14 @@ dmar_gas_match_one(struct dmar_gas_match_args *a, struct dmar_map_entry *prev,
/* /*
* The start + offset to start + offset + size region crosses * The start + offset to start + offset + size region crosses
* the boundary. Check if there is enough space after the * the boundary. Check if there is enough space after the
* next boundary after the prev->end. * next boundary after the beg.
*/ */
bs = rounddown2(a->entry->start + a->offset + a->common->boundary, bs = rounddown2(a->entry->start + a->offset + a->common->boundary,
a->common->boundary); a->common->boundary);
start = roundup2(bs, a->common->alignment); start = roundup2(bs, a->common->alignment);
/* DMAR_PAGE_SIZE to create gap after new entry. */ /* DMAR_PAGE_SIZE to create gap after new entry. */
if (start + a->offset + a->size + DMAR_PAGE_SIZE <= if (start + a->offset + a->size + DMAR_PAGE_SIZE <= end &&
prev->end + prev->free_after && start + a->offset + a->size <= maxaddr &&
start + a->offset + a->size <= end &&
dmar_test_boundary(start + a->offset, a->size, dmar_test_boundary(start + a->offset, a->size,
a->common->boundary)) { a->common->boundary)) {
a->entry->start = start; a->entry->start = start;
@ -346,7 +322,7 @@ dmar_gas_match_one(struct dmar_gas_match_args *a, struct dmar_map_entry *prev,
/* /*
* Not enough space to align at the requested boundary, or * Not enough space to align at the requested boundary, or
* boundary is smaller than the size, but allowed to split. * boundary is smaller than the size, but allowed to split.
* We already checked that start + size does not overlap end. * We already checked that start + size does not overlap maxaddr.
* *
* XXXKIB. It is possible that bs is exactly at the start of * XXXKIB. It is possible that bs is exactly at the start of
* the next entry, then we do not have gap. Ignore for now. * the next entry, then we do not have gap. Ignore for now.
@ -360,10 +336,8 @@ dmar_gas_match_one(struct dmar_gas_match_args *a, struct dmar_map_entry *prev,
} }
static void static void
dmar_gas_match_insert(struct dmar_gas_match_args *a, dmar_gas_match_insert(struct dmar_gas_match_args *a)
struct dmar_map_entry *prev)
{ {
struct dmar_map_entry *next;
bool found; bool found;
/* /*
@ -376,102 +350,67 @@ dmar_gas_match_insert(struct dmar_gas_match_args *a,
*/ */
a->entry->end = a->entry->start + a->size; a->entry->end = a->entry->start + a->size;
next = RB_NEXT(dmar_gas_entries_tree, &a->domain->rb_root, prev);
KASSERT(next->start >= a->entry->end &&
next->start - a->entry->start >= a->size &&
prev->end <= a->entry->end,
("dmar_gas_match_insert hole failed %p prev (%jx, %jx) "
"free_after %jx next (%jx, %jx) entry (%jx, %jx)", a->domain,
(uintmax_t)prev->start, (uintmax_t)prev->end,
(uintmax_t)prev->free_after,
(uintmax_t)next->start, (uintmax_t)next->end,
(uintmax_t)a->entry->start, (uintmax_t)a->entry->end));
prev->free_after = a->entry->start - prev->end;
a->entry->free_after = next->start - a->entry->end;
found = dmar_gas_rb_insert(a->domain, a->entry); found = dmar_gas_rb_insert(a->domain, a->entry);
KASSERT(found, ("found dup %p start %jx size %jx", KASSERT(found, ("found dup %p start %jx size %jx",
a->domain, (uintmax_t)a->entry->start, (uintmax_t)a->size)); a->domain, (uintmax_t)a->entry->start, (uintmax_t)a->size));
a->entry->flags = DMAR_MAP_ENTRY_MAP; a->entry->flags = DMAR_MAP_ENTRY_MAP;
KASSERT(RB_PREV(dmar_gas_entries_tree, &a->domain->rb_root,
a->entry) == prev,
("entry %p prev %p inserted prev %p", a->entry, prev,
RB_PREV(dmar_gas_entries_tree, &a->domain->rb_root, a->entry)));
KASSERT(RB_NEXT(dmar_gas_entries_tree, &a->domain->rb_root,
a->entry) == next,
("entry %p next %p inserted next %p", a->entry, next,
RB_NEXT(dmar_gas_entries_tree, &a->domain->rb_root, a->entry)));
} }
static int static int
dmar_gas_lowermatch(struct dmar_gas_match_args *a, struct dmar_map_entry *prev) dmar_gas_lowermatch(struct dmar_gas_match_args *a, struct dmar_map_entry *entry)
{ {
struct dmar_map_entry *l; struct dmar_map_entry *child;
int ret;
if (prev->end < a->common->lowaddr) { child = RB_RIGHT(entry, rb_entry);
a->entry->start = roundup2(prev->end + DMAR_PAGE_SIZE, if (child != NULL && entry->end < a->common->lowaddr &&
a->common->alignment); dmar_gas_match_one(a, entry->end, child->first,
if (dmar_gas_match_one(a, prev, a->common->lowaddr)) { a->common->lowaddr)) {
dmar_gas_match_insert(a, prev); dmar_gas_match_insert(a);
return (0); return (0);
}
} }
if (prev->free_down < a->size + a->offset + DMAR_PAGE_SIZE) if (entry->free_down < a->size + a->offset + DMAR_PAGE_SIZE)
return (ENOMEM); return (ENOMEM);
l = RB_LEFT(prev, rb_entry); child = RB_LEFT(entry, rb_entry);
if (l != NULL) { if (child != NULL && 0 == dmar_gas_lowermatch(a, child))
ret = dmar_gas_lowermatch(a, l); return (0);
if (ret == 0) if (child != NULL && child->last < a->common->lowaddr &&
return (0); dmar_gas_match_one(a, child->last, entry->start,
a->common->lowaddr)) {
dmar_gas_match_insert(a);
return (0);
} }
l = RB_RIGHT(prev, rb_entry); child = RB_RIGHT(entry, rb_entry);
if (l != NULL) if (child != NULL && 0 == dmar_gas_lowermatch(a, child))
return (dmar_gas_lowermatch(a, l)); return (0);
return (ENOMEM); return (ENOMEM);
} }
static int static int
dmar_gas_uppermatch(struct dmar_gas_match_args *a) dmar_gas_uppermatch(struct dmar_gas_match_args *a, struct dmar_map_entry *entry)
{ {
struct dmar_map_entry *next, *prev, find_entry; struct dmar_map_entry *child;
find_entry.start = a->common->highaddr; if (entry->last < a->common->highaddr)
next = RB_NFIND(dmar_gas_entries_tree, &a->domain->rb_root,
&find_entry);
if (next == NULL)
return (ENOMEM); return (ENOMEM);
prev = RB_PREV(dmar_gas_entries_tree, &a->domain->rb_root, next); child = RB_LEFT(entry, rb_entry);
KASSERT(prev != NULL, ("no prev %p %jx", a->domain, if (child != NULL && 0 == dmar_gas_uppermatch(a, child))
(uintmax_t)find_entry.start)); return (0);
for (;;) { if (child != NULL && child->last >= a->common->highaddr &&
a->entry->start = prev->start + DMAR_PAGE_SIZE; dmar_gas_match_one(a, child->last, entry->start,
if (a->entry->start < a->common->highaddr) a->domain->end)) {
a->entry->start = a->common->highaddr; dmar_gas_match_insert(a);
a->entry->start = roundup2(a->entry->start, return (0);
a->common->alignment);
if (dmar_gas_match_one(a, prev, a->domain->end)) {
dmar_gas_match_insert(a, prev);
return (0);
}
/*
* XXXKIB. This falls back to linear iteration over
* the free space in the high region. But high
* regions are almost unused, the code should be
* enough to cover the case, although in the
* non-optimal way.
*/
prev = next;
next = RB_NEXT(dmar_gas_entries_tree, &a->domain->rb_root,
prev);
KASSERT(next != NULL, ("no next %p %jx", a->domain,
(uintmax_t)find_entry.start));
if (next->end >= a->domain->end)
return (ENOMEM);
} }
child = RB_RIGHT(entry, rb_entry);
if (child != NULL && entry->end >= a->common->highaddr &&
dmar_gas_match_one(a, entry->end, child->first,
a->domain->end)) {
dmar_gas_match_insert(a);
return (0);
}
if (child != NULL && 0 == dmar_gas_uppermatch(a, child))
return (0);
return (ENOMEM);
} }
static int static int
@ -504,7 +443,7 @@ dmar_gas_find_space(struct dmar_domain *domain,
/* Handle upper region. */ /* Handle upper region. */
if (common->highaddr >= domain->end) if (common->highaddr >= domain->end)
return (ENOMEM); return (ENOMEM);
error = dmar_gas_uppermatch(&a); error = dmar_gas_uppermatch(&a, RB_ROOT(&domain->rb_root));
KASSERT(error == ENOMEM, KASSERT(error == ENOMEM,
("error %d from dmar_gas_uppermatch", error)); ("error %d from dmar_gas_uppermatch", error));
return (error); return (error);

View File

@ -4189,6 +4189,9 @@ ATF_TC_BODY(ptrace__procdesc_reparent_wait_child, tc)
pid_t traced, debuger, wpid; pid_t traced, debuger, wpid;
int pd, status; int pd, status;
if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
atf_tc_skip("https://bugs.freebsd.org/243605");
traced = pdfork(&pd, 0); traced = pdfork(&pd, 0);
ATF_REQUIRE(traced >= 0); ATF_REQUIRE(traced >= 0);
if (traced == 0) { if (traced == 0) {

View File

@ -1,5 +1,7 @@
# $FreeBSD$ # $FreeBSD$
PACKAGE= tests
TESTSDIR= ${TESTSBASE}/sys/netinet TESTSDIR= ${TESTSBASE}/sys/netinet
BINDIR= ${TESTSDIR} BINDIR= ${TESTSDIR}

View File

@ -4,11 +4,16 @@
LIB= egacy LIB= egacy
SRC= SRC=
INCSGROUPS= INCS SYSINCS CASPERINC INCSGROUPS= INCS SYSINCS CASPERINC UFSINCS FFSINCS MSDOSFSINCS DISKINCS
INCS= INCS=
SYSINCSDIR= ${INCLUDEDIR}/sys SYSINCSDIR= ${INCLUDEDIR}/sys
CASPERINCDIR= ${INCLUDEDIR}/casper CASPERINCDIR= ${INCLUDEDIR}/casper
# Also add ufs/ffs/msdosfs/disk headers to allow building makefs as a bootstrap tool
UFSINCSDIR= ${INCLUDEDIR}/ufs/ufs
FFSINCSDIR= ${INCLUDEDIR}/ufs/ffs
MSDOSFSINCSDIR= ${INCLUDEDIR}/fs/msdosfs
DISKINCSDIR= ${INCLUDEDIR}/sys/disk
BOOTSTRAPPING?= 0 BOOTSTRAPPING?= 0
@ -70,6 +75,19 @@ SRCS= dummy.c
SUBDIR= cross-build SUBDIR= cross-build
.endif .endif
# To allow bootstrapping makefs on FreeBSD 11 or non-FreeBSD systems:
UFSINCS+= ${SRCTOP}/sys/ufs/ufs/dinode.h
UFSINCS+= ${SRCTOP}/sys/ufs/ufs/dir.h
FFSINCS+= ${SRCTOP}/sys/ufs/ffs/fs.h
MSDOSFSINCS+= ${SRCTOP}/sys/fs/msdosfs/bootsect.h
MSDOSFSINCS+= ${SRCTOP}/sys/fs/msdosfs/bpb.h
MSDOSFSINCS+= ${SRCTOP}/sys/fs/msdosfs/denode.h
MSDOSFSINCS+= ${SRCTOP}/sys/fs/msdosfs/direntry.h
MSDOSFSINCS+= ${SRCTOP}/sys/fs/msdosfs/fat.h
MSDOSFSINCS+= ${SRCTOP}/sys/fs/msdosfs/msdosfsmount.h
DISKINCS+= ${SRCTOP}/sys/sys/disk/bsd.h
# Needed to build config (since it uses libnv) # Needed to build config (since it uses libnv)
SYSINCS+= ${SRCTOP}/sys/sys/nv.h ${SRCTOP}/sys/sys/cnv.h \ SYSINCS+= ${SRCTOP}/sys/sys/nv.h ${SRCTOP}/sys/sys/cnv.h \
${SRCTOP}/sys/sys/dnv.h ${SRCTOP}/sys/sys/dnv.h

View File

@ -12,7 +12,7 @@
# #
BASE=/usr/share/libxo BASE=/usr/share/libxo
VERSION=1.3.1 VERSION=1.4.0
CMD=cat CMD=cat
DONE= DONE=
WEB=http://juniper.github.io/libxo/${VERSION}/xohtml WEB=http://juniper.github.io/libxo/${VERSION}/xohtml

View File

@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h> #include <sys/param.h>
#include <sys/errno.h> #include <sys/errno.h>
#include <sys/vnode.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
@ -288,10 +287,7 @@ detrunc(struct denode *dep, u_long length, int flags, struct ucred *cred)
return (error); return (error);
} }
memset(bp->b_data + boff, 0, pmp->pm_bpcluster - boff); memset(bp->b_data + boff, 0, pmp->pm_bpcluster - boff);
if (flags & IO_SYNC)
bwrite(bp); bwrite(bp);
else
bdwrite(bp);
} }
} }

View File

@ -103,7 +103,11 @@ msdosfs_times(struct denode *dep, const struct stat *st)
if (stampst.st_ino) if (stampst.st_ino)
st = &stampst; st = &stampst;
#ifdef HAVE_STRUCT_STAT_BIRTHTIME
unix2fattime(&st->st_birthtim, &dep->de_CDate, &dep->de_CTime); unix2fattime(&st->st_birthtim, &dep->de_CDate, &dep->de_CTime);
#else
unix2fattime(&st->st_ctim, &dep->de_CDate, &dep->de_CTime);
#endif
unix2fattime(&st->st_atim, &dep->de_ADate, NULL); unix2fattime(&st->st_atim, &dep->de_ADate, NULL);
unix2fattime(&st->st_mtim, &dep->de_MDate, &dep->de_MTime); unix2fattime(&st->st_mtim, &dep->de_MDate, &dep->de_MTime);
} }