Merge ^/head r357119 through r357178.
This commit is contained in:
parent
803bf5d0e4
commit
7edcf8ccf4
@ -32,7 +32,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd March 7, 2017
|
||||
.Dd January 26, 2020
|
||||
.Dt PWAIT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -41,7 +41,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl t Ar duration
|
||||
.Op Fl v
|
||||
.Op Fl ov
|
||||
.Ar pid
|
||||
\&...
|
||||
.Sh DESCRIPTION
|
||||
@ -51,6 +51,8 @@ utility will wait until each of the given processes has terminated.
|
||||
.Pp
|
||||
The following option is available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl o
|
||||
Exit when any of the given processes has terminated.
|
||||
.It Fl t Ar duration
|
||||
If any process is still running after
|
||||
.Ar duration ,
|
||||
|
@ -53,8 +53,7 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: pwait [-t timeout] [-v] pid ...\n");
|
||||
exit(EX_USAGE);
|
||||
errx(EX_USAGE, "usage: pwait [-t timeout] [-ov] pid ...");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -64,25 +63,30 @@ int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct itimerval itv;
|
||||
int kq;
|
||||
struct kevent *e;
|
||||
int tflag, verbose;
|
||||
int opt, nleft, n, i, duplicate, status;
|
||||
int oflag, tflag, verbose;
|
||||
int i, kq, n, nleft, opt, status;
|
||||
long pid;
|
||||
char *s, *end;
|
||||
char *end, *s;
|
||||
double timeout;
|
||||
|
||||
tflag = verbose = 0;
|
||||
oflag = 0;
|
||||
tflag = 0;
|
||||
verbose = 0;
|
||||
memset(&itv, 0, sizeof(itv));
|
||||
while ((opt = getopt(argc, argv, "t:v")) != -1) {
|
||||
|
||||
while ((opt = getopt(argc, argv, "ot:v")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
oflag = 1;
|
||||
break;
|
||||
case 't':
|
||||
tflag = 1;
|
||||
errno = 0;
|
||||
timeout = strtod(optarg, &end);
|
||||
if (end == optarg || errno == ERANGE ||
|
||||
timeout < 0)
|
||||
if (end == optarg || errno == ERANGE || timeout < 0) {
|
||||
errx(EX_DATAERR, "timeout value");
|
||||
}
|
||||
switch(*end) {
|
||||
case 0:
|
||||
case 's':
|
||||
@ -96,8 +100,9 @@ main(int argc, char *argv[])
|
||||
default:
|
||||
errx(EX_DATAERR, "timeout unit");
|
||||
}
|
||||
if (timeout > 100000000L)
|
||||
if (timeout > 100000000L) {
|
||||
errx(EX_DATAERR, "timeout value");
|
||||
}
|
||||
itv.it_value.tv_sec = (time_t)timeout;
|
||||
timeout -= (time_t)timeout;
|
||||
itv.it_value.tv_usec =
|
||||
@ -115,77 +120,96 @@ main(int argc, char *argv[])
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0)
|
||||
if (argc == 0) {
|
||||
usage();
|
||||
}
|
||||
|
||||
kq = kqueue();
|
||||
if (kq == -1)
|
||||
err(1, "kqueue");
|
||||
if (kq == -1) {
|
||||
err(EX_OSERR, "kqueue");
|
||||
}
|
||||
|
||||
e = malloc((argc + tflag) * sizeof(struct kevent));
|
||||
if (e == NULL)
|
||||
err(1, "malloc");
|
||||
if (e == NULL) {
|
||||
err(EX_OSERR, "malloc");
|
||||
}
|
||||
nleft = 0;
|
||||
for (n = 0; n < argc; n++) {
|
||||
s = argv[n];
|
||||
if (!strncmp(s, "/proc/", 6)) /* Undocumented Solaris compat */
|
||||
/* Undocumented Solaris compat */
|
||||
if (!strncmp(s, "/proc/", 6)) {
|
||||
s += 6;
|
||||
}
|
||||
errno = 0;
|
||||
pid = strtol(s, &end, 10);
|
||||
if (pid < 0 || *end != '\0' || errno != 0) {
|
||||
warnx("%s: bad process id", s);
|
||||
continue;
|
||||
}
|
||||
duplicate = 0;
|
||||
for (i = 0; i < nleft; i++)
|
||||
if (e[i].ident == (uintptr_t)pid)
|
||||
duplicate = 1;
|
||||
if (!duplicate) {
|
||||
EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT,
|
||||
0, NULL);
|
||||
if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1)
|
||||
warn("%ld", pid);
|
||||
else
|
||||
nleft++;
|
||||
for (i = 0; i < nleft; i++) {
|
||||
if (e[i].ident == (uintptr_t)pid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < nleft) {
|
||||
/* Duplicate. */
|
||||
continue;
|
||||
}
|
||||
EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
|
||||
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
|
||||
* can be returned rather than 142.
|
||||
*/
|
||||
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");
|
||||
}
|
||||
/* Ignore SIGALRM to not interrupt kevent(2). */
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
|
||||
if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
|
||||
err(EX_OSERR, "setitimer");
|
||||
}
|
||||
}
|
||||
while (nleft > 0) {
|
||||
n = kevent(kq, NULL, 0, e, nleft + tflag, NULL);
|
||||
if (n == -1)
|
||||
err(1, "kevent");
|
||||
if (n == -1) {
|
||||
err(EX_OSERR, "kevent");
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
if (e[i].filter == EVFILT_SIGNAL) {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
printf("timeout\n");
|
||||
return (124);
|
||||
}
|
||||
exit(124);
|
||||
}
|
||||
if (verbose) {
|
||||
status = e[i].data;
|
||||
if (WIFEXITED(status))
|
||||
if (WIFEXITED(status)) {
|
||||
printf("%ld: exited with status %d.\n",
|
||||
(long)e[i].ident,
|
||||
WEXITSTATUS(status));
|
||||
else if (WIFSIGNALED(status))
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
printf("%ld: killed by signal %d.\n",
|
||||
(long)e[i].ident,
|
||||
WTERMSIG(status));
|
||||
else
|
||||
} else {
|
||||
printf("%ld: terminated.\n",
|
||||
(long)e[i].ident);
|
||||
}
|
||||
}
|
||||
if (oflag) {
|
||||
exit(EX_OK);
|
||||
}
|
||||
--nleft;
|
||||
}
|
||||
|
@ -232,6 +232,85 @@ timeout_many_cleanup()
|
||||
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_add_test_case basic
|
||||
@ -239,4 +318,5 @@ atf_init_test_cases()
|
||||
atf_add_test_case timeout_trigger_timeout
|
||||
atf_add_test_case timeout_no_timeout
|
||||
atf_add_test_case timeout_many
|
||||
atf_add_test_case or_flag
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#
|
||||
|
||||
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])
|
||||
|
||||
# Support silent build rules. Requires at least automake-1.11.
|
||||
|
@ -1204,6 +1204,11 @@ message associated with either *errno* or the *code* parameter::
|
||||
xo_err(1, "cannot open file '%s'", filename);
|
||||
|
||||
.. index:: xo_error
|
||||
.. index:: xo_error_h
|
||||
.. index:: xo_error_hv
|
||||
.. index:: xo_errorn
|
||||
.. index:: xo_errorn_h
|
||||
.. index:: xo_errorn_hv
|
||||
|
||||
xo_error
|
||||
~~~~~~~~
|
||||
@ -1214,6 +1219,50 @@ xo_error
|
||||
:type fmt: const char *
|
||||
: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
|
||||
be reported over the handle, rather than to stderr. The `xo_error`
|
||||
function behaves like `xo_err` for TEXT and HTML output styles, but
|
||||
@ -1226,6 +1275,16 @@ xo_error
|
||||
JSON::
|
||||
"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:: Locale
|
||||
|
||||
|
@ -26,12 +26,13 @@ example uses the "cbor" encoder, saving the output into a file::
|
||||
df --libxo encoder=cbor > df-output.cbor
|
||||
|
||||
Encoders can support specific options that can be accessed by
|
||||
following the encoder name with a colon (':') and one of more options,
|
||||
separated by a plus sign "+"::
|
||||
following the encoder name with a colon (':') or a plus sign ('+') and
|
||||
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::
|
||||
|
||||
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.
|
||||
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 - Comma Separated Values
|
||||
|
@ -162,3 +162,23 @@ foreground and background output to "yellow", give only the fifth
|
||||
mapping, skipping the first four mappings with bare plus signs ("+")::
|
||||
|
||||
--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
|
||||
|
@ -41,10 +41,12 @@
|
||||
* (double) quote characters.
|
||||
* - Leading and trialing whitespace require fields be quoted.
|
||||
*
|
||||
* Cheesy, but simple. The RFC also requires MS-DOS end-of-line, which
|
||||
* we only do with the "dos" option. Strange that we still live in a
|
||||
* DOS-friendly world, but then again, we make spaceships based on the
|
||||
* horse butts (http://www.astrodigital.org/space/stshorse.html).
|
||||
* Cheesy, but simple. The RFC also requires MS-DOS end-of-line,
|
||||
* which we only do with the "dos" option. Strange that we still live
|
||||
* in a DOS-friendly world, but then again, we make spaceships based
|
||||
* 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>
|
||||
@ -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:
|
||||
* -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
|
||||
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);
|
||||
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;
|
||||
for (cp = options, ep = options + len + 1; cp && cp < ep; cp = np) {
|
||||
np = strchr(cp, '+');
|
||||
np = strchr(cp, opts_char);
|
||||
if (np)
|
||||
*np++ = '\0';
|
||||
|
||||
@ -761,7 +765,11 @@ csv_handler (XO_ENCODER_HANDLER_ARGS)
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case XO_OP_OPEN_LIST:
|
||||
|
@ -2371,6 +2371,25 @@ xo_set_options (xo_handle_t *xop, const char *input)
|
||||
if (np)
|
||||
*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, '=');
|
||||
if (vp)
|
||||
*vp++ = '\0';
|
||||
@ -8007,7 +8026,7 @@ xo_finish_atexit (void)
|
||||
* Generate an error message, such as would be displayed on stderr
|
||||
*/
|
||||
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);
|
||||
|
||||
@ -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
|
||||
* one on ourselves.
|
||||
*/
|
||||
ssize_t len = strlen(fmt);
|
||||
if (len > 0 && fmt[len - 1] != '\n') {
|
||||
char *newfmt = alloca(len + 2);
|
||||
memcpy(newfmt, fmt, len);
|
||||
newfmt[len] = '\n';
|
||||
newfmt[len + 1] = '\0';
|
||||
fmt = newfmt;
|
||||
if (need_newline) {
|
||||
ssize_t len = strlen(fmt);
|
||||
if (len > 0 && fmt[len - 1] != '\n') {
|
||||
char *newfmt = alloca(len + 2);
|
||||
memcpy(newfmt, fmt, len);
|
||||
newfmt[len] = '\n';
|
||||
newfmt[len + 1] = '\0';
|
||||
fmt = newfmt;
|
||||
}
|
||||
}
|
||||
|
||||
switch (xo_style(xop)) {
|
||||
@ -8069,7 +8090,7 @@ xo_error_h (xo_handle_t *xop, const char *fmt, ...)
|
||||
va_list vap;
|
||||
|
||||
va_start(vap, fmt);
|
||||
xo_error_hv(xop, fmt, vap);
|
||||
xo_errorn_hv(xop, 0, fmt, vap);
|
||||
va_end(vap);
|
||||
}
|
||||
|
||||
@ -8082,7 +8103,30 @@ xo_error (const char *fmt, ...)
|
||||
va_list vap;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -8099,21 +8143,30 @@ xo_parse_args (int argc, char **argv)
|
||||
char *cp;
|
||||
int i, save;
|
||||
|
||||
/* Save our program name for xo_err and friends */
|
||||
xo_program = argv[0];
|
||||
cp = strrchr(xo_program, '/');
|
||||
if (cp)
|
||||
xo_program = ++cp;
|
||||
else
|
||||
cp = argv[0]; /* Reset to front of string */
|
||||
/*
|
||||
* If xo_set_program has always been called, we honor that value
|
||||
*/
|
||||
if (xo_program == NULL) {
|
||||
/* Save our program name for xo_err and friends */
|
||||
xo_program = argv[0];
|
||||
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);
|
||||
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';
|
||||
/*
|
||||
* GNU libtool add an annoying ".test" as the program
|
||||
* extension; we remove it. libtool also adds a "lt-" prefix
|
||||
* that we cannot remove.
|
||||
*/
|
||||
size_t len = strlen(xo_program);
|
||||
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);
|
||||
|
@ -389,6 +389,15 @@ xo_error_h (xo_handle_t *xop, const char *fmt, ...);
|
||||
void
|
||||
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_flush_h (xo_handle_t *xop);
|
||||
|
||||
|
@ -290,8 +290,21 @@ xo_encoder_init (xo_handle_t *xop, const char *name)
|
||||
{
|
||||
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) {
|
||||
opts_char = *opts;
|
||||
|
||||
/* Make a writable copy of the name */
|
||||
size_t len = strlen(name);
|
||||
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);
|
||||
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;
|
||||
|
@ -90,6 +90,7 @@ typedef unsigned xo_encoder_op_t;
|
||||
#define XO_OP_ATTRIBUTE 15 /* Attribute name/value */
|
||||
#define XO_OP_VERSION 16 /* Version string */
|
||||
#define XO_OP_OPTIONS 17 /* Additional command line options */
|
||||
#define XO_OP_OPTIONS_PLUS 18 /* Additional command line options */
|
||||
|
||||
#define XO_ENCODER_HANDLER_ARGS \
|
||||
xo_handle_t *xop __attribute__ ((__unused__)), \
|
||||
|
@ -88,7 +88,7 @@ TEST_JIG = \
|
||||
|
||||
TEST_JIG2 = \
|
||||
echo "... $$test ... $$fmt ..."; \
|
||||
xoopts==warn,encoder=csv$$csv ; \
|
||||
xoopts==warn,$$csv ; \
|
||||
${TEST_JIG}; true;
|
||||
|
||||
TEST_FORMATS = T XP JP HP X J H HIPx
|
||||
@ -111,9 +111,12 @@ test tests: ${bin_PROGRAMS}
|
||||
done) \
|
||||
done)
|
||||
-@ (${TEST_TRACE} test=test_01.c; base=test_01; \
|
||||
( fmt=Ecsv1; csv= ; ${TEST_JIG2} ); \
|
||||
( fmt=Ecsv2; csv=:path=top/data/item+no-header ; ${TEST_JIG2} ); \
|
||||
( fmt=Ecsv3; csv=:path=item+leafs=sku.sold+no-quotes ; ${TEST_JIG2} ); \
|
||||
( fmt=Ecsv1; csv=encoder=csv ; \
|
||||
${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
@ -225,3 +225,18 @@
|
||||
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
||||
</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>
|
||||
|
@ -225,3 +225,18 @@
|
||||
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
||||
</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>
|
||||
|
@ -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"}}}}
|
||||
|
@ -80,6 +80,18 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,5 @@
|
||||
test_02: key field emitted after normal value field: 'name'
|
||||
Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
||||
err message (1)err message (2)
|
||||
err message (1)
|
||||
err message (2)
|
||||
|
@ -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><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! <>!,"!<>
|
||||
</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>
|
@ -85,6 +85,21 @@
|
||||
</message>
|
||||
<error>
|
||||
<message>Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
||||
</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>
|
||||
|
@ -21,6 +21,8 @@
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
xo_set_program("test_02");
|
||||
|
||||
argc = xo_parse_args(argc, argv);
|
||||
if (argc < 0)
|
||||
return 1;
|
||||
@ -144,6 +146,10 @@ main (int argc, char **argv)
|
||||
"ten yard penalty", "first down");
|
||||
|
||||
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");
|
||||
|
||||
|
@ -25,6 +25,8 @@ main (int argc, char **argv)
|
||||
xo_emit_flags_t flags = XOEF_RETAIN;
|
||||
int opt_color = 1;
|
||||
|
||||
xo_set_program("test_12");
|
||||
|
||||
argc = xo_parse_args(argc, argv);
|
||||
if (argc < 0)
|
||||
return 1;
|
||||
|
@ -3,10 +3,10 @@
|
||||
.Fx
|
||||
uses
|
||||
.Nm libxo
|
||||
version 1.3.1.
|
||||
version 1.4.0.
|
||||
Complete documentation can be found on github:
|
||||
.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
|
||||
.Pp
|
||||
.Nm libxo
|
||||
|
@ -183,16 +183,16 @@
|
||||
/* #undef LIBXO_TEXT_ONLY */
|
||||
|
||||
/* Version number as dotted value */
|
||||
#define LIBXO_VERSION "1.3.1"
|
||||
#define LIBXO_VERSION "1.4.0"
|
||||
|
||||
/* Version number extra information */
|
||||
#define LIBXO_VERSION_EXTRA ""
|
||||
|
||||
/* Version number as a number */
|
||||
#define LIBXO_VERSION_NUMBER 1003001
|
||||
#define LIBXO_VERSION_NUMBER 1004000
|
||||
|
||||
/* Version number as string */
|
||||
#define LIBXO_VERSION_STRING "1003001"
|
||||
#define LIBXO_VERSION_STRING "1004000"
|
||||
|
||||
/* Enable local wcwidth implementation */
|
||||
#define LIBXO_WCWIDTH 1
|
||||
@ -210,7 +210,7 @@
|
||||
#define PACKAGE_NAME "libxo"
|
||||
|
||||
/* 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 PACKAGE_TARNAME "libxo"
|
||||
@ -219,7 +219,7 @@
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* 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
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
@ -236,7 +236,7 @@
|
||||
/* #undef USE_INT_RETURN_CODES */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.3.1"
|
||||
#define VERSION "1.4.0"
|
||||
|
||||
/* Retain hash bucket size */
|
||||
/* #undef XO_RETAIN_SIZE */
|
||||
|
@ -31,10 +31,15 @@ static const char rcsid[] =
|
||||
#endif /* not lint */
|
||||
|
||||
#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/disk.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
#include <sys/stat.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))
|
||||
warnx("warning, %s is not a regular file", fname);
|
||||
} else {
|
||||
#ifndef MAKEFS
|
||||
#ifdef MAKEFS
|
||||
errx(1, "o.create_size must be set!");
|
||||
#else
|
||||
if (!S_ISCHR(sb.st_mode))
|
||||
warnx("warning, %s is not a character device", fname);
|
||||
#endif
|
||||
}
|
||||
#ifndef MAKEFS
|
||||
if (!o.no_create)
|
||||
if (check_mounted(fname, sb.st_mode) == -1)
|
||||
goto done;
|
||||
#endif
|
||||
if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) {
|
||||
warnx("cannot seek to %jd", (intmax_t)o.offset);
|
||||
goto done;
|
||||
@ -621,10 +630,12 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
|
||||
bpb.bpbBigFATsecs) * bpb.bpbFATs;
|
||||
memset(&si_sa, 0, sizeof(si_sa));
|
||||
si_sa.sa_handler = infohandler;
|
||||
#ifdef SIGINFO
|
||||
if (sigaction(SIGINFO, &si_sa, NULL) == -1) {
|
||||
warn("sigaction SIGINFO");
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
for (lsn = 0; lsn < dir + (fat == 32 ? bpb.bpbSecPerClust : rds); lsn++) {
|
||||
if (got_siginfo) {
|
||||
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
|
||||
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;
|
||||
const char *s1, *s2;
|
||||
size_t len;
|
||||
@ -790,6 +806,7 @@ check_mounted(const char *fname, mode_t mode)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -811,6 +828,23 @@ getstdfmt(const char *fmt, struct bpb *bpb)
|
||||
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.
|
||||
*/
|
||||
@ -819,8 +853,10 @@ getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
|
||||
struct bpb *bpb)
|
||||
{
|
||||
struct disklabel *lp, dlp;
|
||||
off_t hs = 0;
|
||||
#ifndef MAKEFS
|
||||
off_t ms;
|
||||
struct fd_type type;
|
||||
off_t ms, hs = 0;
|
||||
|
||||
lp = NULL;
|
||||
|
||||
@ -832,16 +868,8 @@ getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
|
||||
/* Maybe it's a floppy drive */
|
||||
if (lp == NULL) {
|
||||
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 */
|
||||
ms = st.st_size;
|
||||
dlp.d_secsize = 512;
|
||||
dlp.d_nsectors = 63;
|
||||
dlp.d_ntracks = 255;
|
||||
dlp.d_secperunit = ms / dlp.d_secsize;
|
||||
compute_geometry_from_file(fd, fname, &dlp);
|
||||
lp = &dlp;
|
||||
} else if (ioctl(fd, FD_GTYPE, &type) != -1) {
|
||||
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;
|
||||
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 (ckgeom(fname, lp->d_secsize, "bytes/sector") == -1)
|
||||
|
@ -79,11 +79,10 @@ LIB32CPUFLAGS= -target mips-unknown-freebsd13.0
|
||||
.endif
|
||||
LIB32CPUFLAGS+= -mabi=32
|
||||
LIB32_MACHINE= mips
|
||||
LIB32_MACHINE_ARCH:= ${COMPAT_ARCH:S/64//}
|
||||
.if ${COMPAT_ARCH:Mmips64el*} != ""
|
||||
LIB32_MACHINE_ARCH= mipsel
|
||||
_EMULATION= elf32ltsmip_fbsd
|
||||
.else
|
||||
LIB32_MACHINE_ARCH= mips
|
||||
_EMULATION= elf32btsmip_fbsd
|
||||
.endif
|
||||
LIB32WMAKEFLAGS= LD="${XLD} -m ${_EMULATION}"
|
||||
|
@ -50,12 +50,9 @@ ARCH_FLAGS+=-mabi=${MIPS_ABI}
|
||||
EXTRA_FLAGS=-fno-pic -mno-abicalls -G0 -DKERNLOADADDR=${KERNLOADADDR}
|
||||
EXTRA_FLAGS+=-${MIPS_ENDIAN}
|
||||
|
||||
HACK_EXTRA_FLAGS=-shared
|
||||
|
||||
# We add the -fno-pic flag to kernels because otherwise performance
|
||||
# is extremely poor, as well as -mno-abicalls to force no ABI usage.
|
||||
CFLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS)
|
||||
HACK_EXTRA_FLAGS+=${EXTRA_FLAGS} $(ARCH_FLAGS)
|
||||
TRAMP_ARCH_FLAGS?=$(ARCH_FLAGS)
|
||||
TRAMP_EXTRA_FLAGS=${EXTRA_FLAGS} ${TRAMP_ARCH_FLAGS}
|
||||
# Kernel code is always compiled with soft-float on MIPS
|
||||
|
@ -39,7 +39,6 @@ INCLUDES+= -I$S/contrib/libfdt
|
||||
# Force __SPE__, since the builtin will be removed later with -mno-spe
|
||||
CFLAGS.gcc+= -mabi=spe -D__SPE__
|
||||
CFLAGS.clang+= -mspe -D__SPE__ -m32
|
||||
HACK_EXTRA_FLAGS= -shared -m32 -mspe -D__SPE__
|
||||
.endif
|
||||
CFLAGS+= -msoft-float
|
||||
CFLAGS.gcc+= -Wa,-many
|
||||
|
@ -226,10 +226,9 @@ kernel-clean:
|
||||
# This is a hack. BFD "optimizes" away dynamic mode if there are no
|
||||
# dynamic references. We could probably do a '-Bforcedynamic' mode like
|
||||
# in the a.out ld. For now, this works.
|
||||
HACK_EXTRA_FLAGS?= -shared
|
||||
hack.pico: Makefile
|
||||
:> 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
|
||||
|
||||
offset.inc: $S/kern/genoffset.sh genoffset.o
|
||||
|
@ -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++) {
|
||||
mpt_cmd = sc->mpt_cmd_list[i];
|
||||
|
||||
/*
|
||||
* Check if the target_id and bus_id is same as the timeout IO
|
||||
*/
|
||||
if (mpt_cmd->ccb_ptr) {
|
||||
/* bus_id = 1 denotes a VD */
|
||||
if (bus_id == 1)
|
||||
tgt_id = (mpt_cmd->ccb_ptr->ccb_h.target_id - (MRSAS_MAX_PD - 1));
|
||||
/*
|
||||
* Check if the target_id and bus_id is same as the timeout IO
|
||||
*/
|
||||
if (mpt_cmd->ccb_ptr) {
|
||||
/* bus_id = 1 denotes a VD */
|
||||
if (bus_id == 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 &&
|
||||
mpt_cmd->ccb_ptr->ccb_h.target_id == tgt_id) {
|
||||
|
@ -3374,6 +3374,7 @@ msk_txeof(struct msk_if_softc *sc_if, int idx)
|
||||
static void
|
||||
msk_tick(void *xsc_if)
|
||||
{
|
||||
struct epoch_tracker et;
|
||||
struct msk_if_softc *sc_if;
|
||||
struct mii_data *mii;
|
||||
|
||||
@ -3386,7 +3387,9 @@ msk_tick(void *xsc_if)
|
||||
mii_tick(mii);
|
||||
if ((sc_if->msk_flags & MSK_FLAG_LINK) == 0)
|
||||
msk_miibus_statchg(sc_if->msk_if_dev);
|
||||
NET_EPOCH_ENTER(et);
|
||||
msk_handle_events(sc_if->msk_softc);
|
||||
NET_EPOCH_EXIT(et);
|
||||
msk_watchdog(sc_if);
|
||||
callout_reset(&sc_if->msk_tick_ch, hz, msk_tick, sc_if);
|
||||
}
|
||||
|
@ -1523,11 +1523,12 @@ static int
|
||||
netmap_mem_unmap(struct netmap_obj_pool *p, struct netmap_adapter *na)
|
||||
{
|
||||
int i, lim = p->objtotal;
|
||||
struct netmap_lut *lut = &na->na_lut;
|
||||
struct netmap_lut *lut;
|
||||
|
||||
if (na == NULL || na->pdev == NULL)
|
||||
return 0;
|
||||
|
||||
lut = &na->na_lut;
|
||||
#if defined(__FreeBSD__)
|
||||
/* On FreeBSD mapping and unmapping is performed by the txsync
|
||||
* and rxsync routine, packet by packet. */
|
||||
|
@ -1257,11 +1257,12 @@ emu_intr(void *data)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (stat & EMU_IPR_MIDIRECVBUFE)
|
||||
if (sc->mpu_intr) {
|
||||
(sc->mpu_intr)(sc->mpu);
|
||||
ack |= EMU_IPR_MIDIRECVBUFE | EMU_IPR_MIDITRANSBUFE;
|
||||
}
|
||||
if (stat & EMU_IPR_MIDIRECVBUFE) {
|
||||
if (sc->mpu_intr) {
|
||||
(sc->mpu_intr)(sc->mpu);
|
||||
ack |= EMU_IPR_MIDIRECVBUFE | EMU_IPR_MIDITRANSBUFE;
|
||||
}
|
||||
}
|
||||
if (stat & ~ack)
|
||||
device_printf(sc->dev, "dodgy irq: %x (harmless)\n",
|
||||
stat & ~ack);
|
||||
|
@ -263,11 +263,12 @@ emu_dspmixer_uninit(struct snd_mixer *m)
|
||||
|
||||
/* drop submixer for AC97 codec */
|
||||
sc = mix_getdevinfo(m);
|
||||
if (sc->sm != NULL)
|
||||
if (sc->sm != NULL) {
|
||||
err = mixer_delete(sc->sm);
|
||||
if (err)
|
||||
return (err);
|
||||
sc->sm = NULL;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -56,8 +56,10 @@
|
||||
#if defined (_KERNEL) || defined(MAKEFS)
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef MAKEFS
|
||||
#include <sys/lock.h>
|
||||
#include <sys/lockmgr.h>
|
||||
#endif
|
||||
#include <sys/tree.h>
|
||||
|
||||
#ifdef MALLOC_DECLARE
|
||||
@ -110,7 +112,9 @@ struct msdosfsmount {
|
||||
void *pm_w2u; /* Unicode->Local iconv handle */
|
||||
void *pm_u2d; /* Unicode->DOS iconv handle */
|
||||
void *pm_d2u; /* DOS->Local iconv handle */
|
||||
#ifndef MAKEFS
|
||||
struct lock pm_fatlock; /* lockmgr protecting allocations */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1554,7 +1554,8 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
|
||||
tvp = NULL;
|
||||
else if (vp == NULL && cansleep != 0) {
|
||||
tvp = nfsvno_getvp(&lfp->lf_fh);
|
||||
NFSVOPUNLOCK(tvp);
|
||||
if (tvp != NULL)
|
||||
NFSVOPUNLOCK(tvp);
|
||||
} else
|
||||
tvp = vp;
|
||||
gottvp = 1;
|
||||
|
@ -1134,8 +1134,11 @@ g_std_done(struct bio *bp)
|
||||
bp2->bio_completed += bp->bio_completed;
|
||||
g_destroy_bio(bp);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: maybe this is only g_slice_spoiled */
|
||||
|
@ -298,6 +298,8 @@ g_stripe_done(struct bio *bp)
|
||||
mtx_unlock(&sc->sc_lock);
|
||||
if (pbp->bio_driver1 != NULL)
|
||||
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);
|
||||
} else
|
||||
mtx_unlock(&sc->sc_lock);
|
||||
|
@ -1450,20 +1450,7 @@ vop_sigdefer(struct vop_vector *vop, struct vop_generic_args *a)
|
||||
vop_bypass_t *bp;
|
||||
int prev_stops, rc;
|
||||
|
||||
for (; vop != NULL; vop = vop->vop_default) {
|
||||
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;
|
||||
}
|
||||
bp = bp_by_off(vop, a);
|
||||
MPASS(bp != NULL);
|
||||
|
||||
prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT);
|
||||
|
@ -2911,7 +2911,8 @@ vget_finish(struct vnode *vp, int flags, enum vgetstate vs)
|
||||
__func__));
|
||||
}
|
||||
|
||||
if ((error = vn_lock(vp, flags)) != 0) {
|
||||
error = vn_lock(vp, flags);
|
||||
if (__predict_false(error != 0)) {
|
||||
if (vs == VGET_USECOUNT)
|
||||
vrele(vp);
|
||||
else
|
||||
@ -3323,10 +3324,10 @@ vdbatch_process(struct vdbatch *vd)
|
||||
vp->v_dbatchcpu = NOCPU;
|
||||
}
|
||||
mtx_unlock(&vnode_list_mtx);
|
||||
critical_exit();
|
||||
vd->freevnodes = 0;
|
||||
bzero(vd->tab, sizeof(vd->tab));
|
||||
vd->index = 0;
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -6367,6 +6368,9 @@ __mnt_vnode_first_lazy(struct vnode **mvp, struct mount *mp, mnt_lazy_cb_t *cb,
|
||||
{
|
||||
struct vnode *vp;
|
||||
|
||||
if (TAILQ_EMPTY(&mp->mnt_lazyvnodelist))
|
||||
return (NULL);
|
||||
|
||||
*mvp = vn_alloc_marker(mp);
|
||||
MNT_ILOCK(mp);
|
||||
MNT_REF(mp);
|
||||
|
@ -371,9 +371,11 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
|
||||
case IPVERSION:
|
||||
family = AF_INET;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case IPV6_VERSION >> 4:
|
||||
family = AF_INET6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
m_freem(m);
|
||||
return (EAFNOSUPPORT);
|
||||
|
@ -335,8 +335,12 @@ struct { \
|
||||
RB_COLOR(red, field) = RB_RED; \
|
||||
} 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
|
||||
#define RB_AUGMENT(x) do {} while (0)
|
||||
#define RB_AUGMENT(x) break
|
||||
#endif
|
||||
|
||||
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
|
||||
@ -344,7 +348,6 @@ struct { \
|
||||
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
|
||||
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
@ -354,9 +357,7 @@ struct { \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_LEFT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
if ((RB_PARENT(tmp, field))) \
|
||||
RB_AUGMENT(RB_PARENT(tmp, field)); \
|
||||
RB_AUGMENT(elm); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
|
||||
@ -364,7 +365,6 @@ struct { \
|
||||
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
|
||||
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
@ -374,9 +374,7 @@ struct { \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_RIGHT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
if ((RB_PARENT(tmp, field))) \
|
||||
RB_AUGMENT(RB_PARENT(tmp, field)); \
|
||||
RB_AUGMENT(elm); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
/* 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) \
|
||||
child = RB_LEFT(elm, field); \
|
||||
else { \
|
||||
struct type *left; \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while ((left = RB_LEFT(elm, field)) != NULL) \
|
||||
elm = left; \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
elm = RB_RIGHT(old, field); \
|
||||
if ((child = RB_LEFT(elm, field)) == NULL) { \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
RB_RIGHT(old, field) = child; \
|
||||
RB_PARENT(elm, field) = elm; \
|
||||
} else { \
|
||||
do \
|
||||
elm = child; \
|
||||
while ((child = RB_LEFT(elm, field)) != NULL); \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
|
||||
} \
|
||||
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 \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
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)); \
|
||||
RB_RIGHT(parent, field) = elm; \
|
||||
} else \
|
||||
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); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
if (child != NULL) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (parent != NULL) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
color: \
|
||||
if (elm != old) \
|
||||
(elm)->field = (old)->field; \
|
||||
if (color == RB_BLACK) \
|
||||
name##_RB_REMOVE_COLOR(head, parent, child); \
|
||||
while (parent != NULL) { \
|
||||
RB_AUGMENT(parent); \
|
||||
parent = RB_PARENT(parent, field); \
|
||||
} \
|
||||
return (old); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define RB_GENERATE_INSERT(name, type, field, cmp, attr) \
|
||||
/* 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; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = elm; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
name##_RB_INSERT_COLOR(head, elm); \
|
||||
while (elm != NULL) { \
|
||||
RB_AUGMENT(elm); \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
} \
|
||||
return (NULL); \
|
||||
}
|
||||
|
||||
|
@ -367,14 +367,11 @@ while ((getline < srcfile) > 0) {
|
||||
add_pre(name);
|
||||
for (i = 0; i < numargs; ++i)
|
||||
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} else {")
|
||||
printc("\t\tSDT_PROBE2(vfs, vop, " name ", entry, a->a_" args[0] ", a);");
|
||||
printc("\t\tif (vop->"name" != NULL)")
|
||||
printc("\t\t\trc = vop->"name"(a);")
|
||||
printc("\t\telse")
|
||||
printc("\t\t\trc = vop->vop_bypass(&a->a_gen);")
|
||||
printc("\t\trc = vop->"name"(a);")
|
||||
printc("\t\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);");
|
||||
printc("\t}")
|
||||
printc("\tif (rc == 0) {");
|
||||
@ -450,6 +447,11 @@ if (cfile) {
|
||||
printc("\tif (vop != NULL)");
|
||||
printc("\t\torig_vop->vop_bypass = vop->vop_bypass;");
|
||||
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("}")
|
||||
}
|
||||
|
@ -1787,6 +1787,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
|
||||
* still zero, it will be unlinked and returned to the free
|
||||
* list by vput().
|
||||
*/
|
||||
vgone(vp);
|
||||
vput(vp);
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
@ -1797,6 +1798,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
|
||||
ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK);
|
||||
if ((error = ffs_load_inode(bp, ip, fs, ino)) != 0) {
|
||||
bqrelse(bp);
|
||||
vgone(vp);
|
||||
vput(vp);
|
||||
*vpp = NULL;
|
||||
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,
|
||||
&vp);
|
||||
if (error) {
|
||||
vgone(vp);
|
||||
vput(vp);
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
@ -1849,6 +1852,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
|
||||
error = mac_vnode_associate_extattr(mp, vp);
|
||||
if (error) {
|
||||
/* ufs_inactive will release ip->i_devvp ref. */
|
||||
vgone(vp);
|
||||
vput(vp);
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
|
@ -1839,6 +1839,7 @@ ufs_mkdir(ap)
|
||||
if (DOINGSOFTDEP(tvp))
|
||||
softdep_revert_link(dp, ip);
|
||||
UFS_VFREE(tvp, ip->i_number, dmode);
|
||||
vgone(tvp);
|
||||
vput(tvp);
|
||||
return (error);
|
||||
}
|
||||
@ -1853,6 +1854,7 @@ ufs_mkdir(ap)
|
||||
if (DOINGSOFTDEP(tvp))
|
||||
softdep_revert_link(dp, ip);
|
||||
UFS_VFREE(tvp, ip->i_number, dmode);
|
||||
vgone(tvp);
|
||||
vput(tvp);
|
||||
return (error);
|
||||
}
|
||||
@ -1980,7 +1982,7 @@ ufs_mkdir(ap)
|
||||
UFS_INODE_SET_FLAG(ip, IN_CHANGE);
|
||||
if (DOINGSOFTDEP(tvp))
|
||||
softdep_revert_mkdir(dp, ip);
|
||||
|
||||
vgone(tvp);
|
||||
vput(tvp);
|
||||
}
|
||||
out:
|
||||
@ -2607,6 +2609,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
|
||||
if (DOINGSOFTDEP(tvp))
|
||||
softdep_revert_link(pdir, ip);
|
||||
UFS_VFREE(tvp, ip->i_number, mode);
|
||||
vgone(tvp);
|
||||
vput(tvp);
|
||||
return (error);
|
||||
}
|
||||
@ -2621,6 +2624,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
|
||||
if (DOINGSOFTDEP(tvp))
|
||||
softdep_revert_link(pdir, ip);
|
||||
UFS_VFREE(tvp, ip->i_number, mode);
|
||||
vgone(tvp);
|
||||
vput(tvp);
|
||||
return (error);
|
||||
}
|
||||
@ -2691,6 +2695,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
|
||||
UFS_INODE_SET_FLAG(ip, IN_CHANGE);
|
||||
if (DOINGSOFTDEP(tvp))
|
||||
softdep_revert_create(VTOI(dvp), ip);
|
||||
vgone(tvp);
|
||||
vput(tvp);
|
||||
return (error);
|
||||
}
|
||||
|
@ -173,8 +173,12 @@ hwpstate_goto_pstate(device_t dev, int id)
|
||||
/* get the current pstate limit */
|
||||
msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
|
||||
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;
|
||||
}
|
||||
|
||||
cpu = curcpu;
|
||||
HWPSTATE_DEBUG(dev, "setting P%d-state on cpu%d\n", id, cpu);
|
||||
|
@ -47,7 +47,8 @@ struct dmar_qi_genseq {
|
||||
struct dmar_map_entry {
|
||||
dmar_gaddr_t start;
|
||||
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
|
||||
current R/B tree node */
|
||||
u_int flags;
|
||||
|
@ -1112,9 +1112,9 @@ dmar_print_domain_entry(const struct dmar_map_entry *entry)
|
||||
struct dmar_map_entry *l, *r;
|
||||
|
||||
db_printf(
|
||||
" start %jx end %jx free_after %jx free_down %jx flags %x ",
|
||||
entry->start, entry->end, entry->free_after, entry->free_down,
|
||||
entry->flags);
|
||||
" start %jx end %jx first %jx last %jx free_down %jx flags %x ",
|
||||
entry->start, entry->end, entry->first, entry->last,
|
||||
entry->free_down, entry->flags);
|
||||
db_printf("left ");
|
||||
l = RB_LEFT(entry, rb_entry);
|
||||
if (l == NULL)
|
||||
|
@ -139,71 +139,52 @@ dmar_gas_cmp_entries(struct dmar_map_entry *a, struct dmar_map_entry *b)
|
||||
static void
|
||||
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)) {
|
||||
l = RB_LEFT(entry, rb_entry);
|
||||
r = RB_RIGHT(entry, rb_entry);
|
||||
if (l == NULL && r == NULL) {
|
||||
entry->free_down = entry->free_after;
|
||||
} else if (l == NULL && r != NULL) {
|
||||
entry->free_down = MAX(entry->free_after, r->free_down);
|
||||
} else if (/*l != NULL && */ r == NULL) {
|
||||
entry->free_down = MAX(entry->free_after, l->free_down);
|
||||
} else /* if (l != NULL && r != NULL) */ {
|
||||
entry->free_down = MAX(entry->free_after, l->free_down);
|
||||
entry->free_down = MAX(entry->free_down, r->free_down);
|
||||
}
|
||||
}
|
||||
free_down = 0;
|
||||
if ((child = RB_LEFT(entry, rb_entry)) != NULL) {
|
||||
free_down = MAX(free_down, child->free_down);
|
||||
free_down = MAX(free_down, entry->start - child->last);
|
||||
entry->first = child->first;
|
||||
} else
|
||||
entry->first = entry->start;
|
||||
|
||||
if ((child = RB_RIGHT(entry, rb_entry)) != NULL) {
|
||||
free_down = MAX(free_down, child->free_down);
|
||||
free_down = MAX(free_down, child->first - entry->end);
|
||||
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,
|
||||
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
|
||||
static void
|
||||
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;
|
||||
|
||||
RB_FOREACH(entry, dmar_gas_entries_tree, &domain->rb_root) {
|
||||
KASSERT(domain == entry->domain,
|
||||
("mismatched free domain %p entry %p entry->domain %p",
|
||||
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);
|
||||
r = RB_RIGHT(entry, rb_entry);
|
||||
if (l == NULL && r == NULL) {
|
||||
MPASS(entry->free_down == entry->free_after);
|
||||
} else if (l == NULL && r != NULL) {
|
||||
MPASS(entry->free_down = MAX(entry->free_after,
|
||||
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);
|
||||
v = 0;
|
||||
if (l != NULL) {
|
||||
v = MAX(v, l->free_down);
|
||||
v = MAX(v, entry->start - l->last);
|
||||
}
|
||||
if (r != NULL) {
|
||||
v = MAX(v, r->free_down);
|
||||
v = MAX(v, r->first - entry->end);
|
||||
}
|
||||
MPASS(entry->free_down == v);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -211,25 +192,17 @@ dmar_gas_check_free(struct dmar_domain *domain)
|
||||
static bool
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
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);
|
||||
if (prev != NULL)
|
||||
dmar_gas_fix_free(domain, prev);
|
||||
}
|
||||
|
||||
void
|
||||
@ -246,13 +219,11 @@ dmar_gas_init_domain(struct dmar_domain *domain)
|
||||
|
||||
begin->start = 0;
|
||||
begin->end = DMAR_PAGE_SIZE;
|
||||
begin->free_after = domain->end - begin->end;
|
||||
begin->flags = DMAR_MAP_ENTRY_PLACE | DMAR_MAP_ENTRY_UNMAPPED;
|
||||
dmar_gas_rb_insert(domain, begin);
|
||||
|
||||
end->start = domain->end;
|
||||
end->end = domain->end;
|
||||
end->free_after = 0;
|
||||
end->flags = DMAR_MAP_ENTRY_PLACE | DMAR_MAP_ENTRY_UNMAPPED;
|
||||
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);
|
||||
KASSERT(entry->start == domain->end, ("end entry start %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,
|
||||
("end entry flags %p", domain));
|
||||
RB_REMOVE(dmar_gas_entries_tree, &domain->rb_root, entry);
|
||||
@ -305,19 +275,26 @@ struct dmar_gas_match_args {
|
||||
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
|
||||
dmar_gas_match_one(struct dmar_gas_match_args *a, struct dmar_map_entry *prev,
|
||||
dmar_gaddr_t end)
|
||||
dmar_gas_match_one(struct dmar_gas_match_args *a, dmar_gaddr_t beg,
|
||||
dmar_gaddr_t end, dmar_gaddr_t maxaddr)
|
||||
{
|
||||
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);
|
||||
|
||||
/* DMAR_PAGE_SIZE to create gap after new entry. */
|
||||
if (a->entry->start < prev->end + DMAR_PAGE_SIZE ||
|
||||
a->entry->start + a->size + a->offset + DMAR_PAGE_SIZE >
|
||||
prev->end + prev->free_after)
|
||||
if (a->entry->start < beg + DMAR_PAGE_SIZE ||
|
||||
a->entry->start + a->size + a->offset + DMAR_PAGE_SIZE > end)
|
||||
return (false);
|
||||
|
||||
/* 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 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,
|
||||
a->common->boundary);
|
||||
start = roundup2(bs, a->common->alignment);
|
||||
/* DMAR_PAGE_SIZE to create gap after new entry. */
|
||||
if (start + a->offset + a->size + DMAR_PAGE_SIZE <=
|
||||
prev->end + prev->free_after &&
|
||||
start + a->offset + a->size <= end &&
|
||||
if (start + a->offset + a->size + DMAR_PAGE_SIZE <= end &&
|
||||
start + a->offset + a->size <= maxaddr &&
|
||||
dmar_test_boundary(start + a->offset, a->size,
|
||||
a->common->boundary)) {
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
dmar_gas_match_insert(struct dmar_gas_match_args *a,
|
||||
struct dmar_map_entry *prev)
|
||||
dmar_gas_match_insert(struct dmar_gas_match_args *a)
|
||||
{
|
||||
struct dmar_map_entry *next;
|
||||
bool found;
|
||||
|
||||
/*
|
||||
@ -376,102 +350,67 @@ dmar_gas_match_insert(struct dmar_gas_match_args *a,
|
||||
*/
|
||||
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);
|
||||
KASSERT(found, ("found dup %p start %jx size %jx",
|
||||
a->domain, (uintmax_t)a->entry->start, (uintmax_t)a->size));
|
||||
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
|
||||
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;
|
||||
int ret;
|
||||
struct dmar_map_entry *child;
|
||||
|
||||
if (prev->end < a->common->lowaddr) {
|
||||
a->entry->start = roundup2(prev->end + DMAR_PAGE_SIZE,
|
||||
a->common->alignment);
|
||||
if (dmar_gas_match_one(a, prev, a->common->lowaddr)) {
|
||||
dmar_gas_match_insert(a, prev);
|
||||
return (0);
|
||||
}
|
||||
child = RB_RIGHT(entry, rb_entry);
|
||||
if (child != NULL && entry->end < a->common->lowaddr &&
|
||||
dmar_gas_match_one(a, entry->end, child->first,
|
||||
a->common->lowaddr)) {
|
||||
dmar_gas_match_insert(a);
|
||||
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);
|
||||
l = RB_LEFT(prev, rb_entry);
|
||||
if (l != NULL) {
|
||||
ret = dmar_gas_lowermatch(a, l);
|
||||
if (ret == 0)
|
||||
return (0);
|
||||
child = RB_LEFT(entry, rb_entry);
|
||||
if (child != NULL && 0 == dmar_gas_lowermatch(a, child))
|
||||
return (0);
|
||||
if (child != NULL && child->last < a->common->lowaddr &&
|
||||
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);
|
||||
if (l != NULL)
|
||||
return (dmar_gas_lowermatch(a, l));
|
||||
child = RB_RIGHT(entry, rb_entry);
|
||||
if (child != NULL && 0 == dmar_gas_lowermatch(a, child))
|
||||
return (0);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
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;
|
||||
next = RB_NFIND(dmar_gas_entries_tree, &a->domain->rb_root,
|
||||
&find_entry);
|
||||
if (next == NULL)
|
||||
if (entry->last < a->common->highaddr)
|
||||
return (ENOMEM);
|
||||
prev = RB_PREV(dmar_gas_entries_tree, &a->domain->rb_root, next);
|
||||
KASSERT(prev != NULL, ("no prev %p %jx", a->domain,
|
||||
(uintmax_t)find_entry.start));
|
||||
for (;;) {
|
||||
a->entry->start = prev->start + DMAR_PAGE_SIZE;
|
||||
if (a->entry->start < a->common->highaddr)
|
||||
a->entry->start = a->common->highaddr;
|
||||
a->entry->start = roundup2(a->entry->start,
|
||||
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_LEFT(entry, rb_entry);
|
||||
if (child != NULL && 0 == dmar_gas_uppermatch(a, child))
|
||||
return (0);
|
||||
if (child != NULL && child->last >= a->common->highaddr &&
|
||||
dmar_gas_match_one(a, child->last, entry->start,
|
||||
a->domain->end)) {
|
||||
dmar_gas_match_insert(a);
|
||||
return (0);
|
||||
}
|
||||
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
|
||||
@ -504,7 +443,7 @@ dmar_gas_find_space(struct dmar_domain *domain,
|
||||
/* Handle upper region. */
|
||||
if (common->highaddr >= domain->end)
|
||||
return (ENOMEM);
|
||||
error = dmar_gas_uppermatch(&a);
|
||||
error = dmar_gas_uppermatch(&a, RB_ROOT(&domain->rb_root));
|
||||
KASSERT(error == ENOMEM,
|
||||
("error %d from dmar_gas_uppermatch", error));
|
||||
return (error);
|
||||
|
@ -4189,6 +4189,9 @@ ATF_TC_BODY(ptrace__procdesc_reparent_wait_child, tc)
|
||||
pid_t traced, debuger, wpid;
|
||||
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);
|
||||
ATF_REQUIRE(traced >= 0);
|
||||
if (traced == 0) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PACKAGE= tests
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/sys/netinet
|
||||
BINDIR= ${TESTSDIR}
|
||||
|
||||
|
@ -4,11 +4,16 @@
|
||||
|
||||
LIB= egacy
|
||||
SRC=
|
||||
INCSGROUPS= INCS SYSINCS CASPERINC
|
||||
INCSGROUPS= INCS SYSINCS CASPERINC UFSINCS FFSINCS MSDOSFSINCS DISKINCS
|
||||
INCS=
|
||||
|
||||
SYSINCSDIR= ${INCLUDEDIR}/sys
|
||||
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
|
||||
|
||||
@ -70,6 +75,19 @@ SRCS= dummy.c
|
||||
SUBDIR= cross-build
|
||||
.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)
|
||||
SYSINCS+= ${SRCTOP}/sys/sys/nv.h ${SRCTOP}/sys/sys/cnv.h \
|
||||
${SRCTOP}/sys/sys/dnv.h
|
||||
|
@ -12,7 +12,7 @@
|
||||
#
|
||||
|
||||
BASE=/usr/share/libxo
|
||||
VERSION=1.3.1
|
||||
VERSION=1.4.0
|
||||
CMD=cat
|
||||
DONE=
|
||||
WEB=http://juniper.github.io/libxo/${VERSION}/xohtml
|
||||
|
@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
@ -288,10 +287,7 @@ detrunc(struct denode *dep, u_long length, int flags, struct ucred *cred)
|
||||
return (error);
|
||||
}
|
||||
memset(bp->b_data + boff, 0, pmp->pm_bpcluster - boff);
|
||||
if (flags & IO_SYNC)
|
||||
bwrite(bp);
|
||||
else
|
||||
bdwrite(bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,11 @@ msdosfs_times(struct denode *dep, const struct stat *st)
|
||||
if (stampst.st_ino)
|
||||
st = &stampst;
|
||||
|
||||
#ifdef HAVE_STRUCT_STAT_BIRTHTIME
|
||||
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_mtim, &dep->de_MDate, &dep->de_MTime);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user