Merge ^/head r357119 through r357178.
This commit is contained in:
commit
773bec0868
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang1000-import/; revision=357179
@ -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 ,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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__)), \
|
||||||
|
@ -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
@ -225,3 +225,18 @@
|
|||||||
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
||||||
</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>
|
||||||
|
@ -225,3 +225,18 @@
|
|||||||
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
<div class="error">Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
||||||
</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>
|
||||||
|
@ -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,
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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! <>!,"!<>
|
</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>
|
</message></error></data></top>
|
@ -85,6 +85,21 @@
|
|||||||
</message>
|
</message>
|
||||||
<error>
|
<error>
|
||||||
<message>Shut 'er down, Clancey! She's a-pumpin' mud! <>!,"!<>
|
<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>
|
</message>
|
||||||
</error>
|
</error>
|
||||||
</data>
|
</data>
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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}"
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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. */
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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("}")
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
|
PACKAGE= tests
|
||||||
|
|
||||||
TESTSDIR= ${TESTSBASE}/sys/netinet
|
TESTSDIR= ${TESTSBASE}/sys/netinet
|
||||||
BINDIR= ${TESTSDIR}
|
BINDIR= ${TESTSDIR}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user