Merge ^/head r279995 through r280029.
This commit is contained in:
+26
-91
@@ -1,18 +1,13 @@
|
||||
$Id: INSTALL,v 1.9 2014/12/11 07:44:46 schwarze Exp $
|
||||
$Id: INSTALL,v 1.10 2015/03/09 21:00:14 schwarze Exp $
|
||||
|
||||
About mdocml, the portable mandoc distribution
|
||||
----------------------------------------------
|
||||
The mandoc manpage compiler toolset is a suite of tools compiling
|
||||
mdoc(7), the roff(7) macro language of choice for BSD manual pages,
|
||||
and man(7), the predominant historical language for UNIX manuals.
|
||||
Since the present version 1.13.2, it includes a man(1) manual viewer
|
||||
in addition to the apropos(1) manual page search tool.
|
||||
It includes a man(1) manual viewer and additional tools.
|
||||
For general information, see <http://mdocml.bsd.lv/>.
|
||||
|
||||
In this document, we describe the installation and deployment of
|
||||
mandoc(1), first as a simple, standalone formatter, and then as part of
|
||||
the man(1) system.
|
||||
|
||||
In case you have questions or want to provide feedback, read
|
||||
<http://mdocml.bsd.lv/contact.html>. Consider subscribing to the
|
||||
discuss@ mailing list mentioned on that page. If you intend to
|
||||
@@ -21,7 +16,7 @@ tech@ mailing list, too.
|
||||
|
||||
Enjoy using the mandoc toolset!
|
||||
|
||||
Ingo Schwarze, Karlsruhe, December 2014
|
||||
Ingo Schwarze, Karlsruhe, March 2015
|
||||
|
||||
|
||||
Installation
|
||||
@@ -32,10 +27,6 @@ or available via a binary package or a ports system. A list of the
|
||||
latest bundled and ported versions of mandoc for various operating
|
||||
systems is maintained at <http://mdocml.bsd.lv/ports.html>.
|
||||
|
||||
If mandoc is installed, you can check the version by running "mandoc -V".
|
||||
You can find the version contained in this distribution tarball
|
||||
by running "./configure".
|
||||
|
||||
Regarding how packages and ports are maintained for your operating
|
||||
system, please consult your operating system documentation.
|
||||
To install mandoc manually, the following steps are needed:
|
||||
@@ -66,17 +57,34 @@ package using some kind of fake root mechanism, you may need a
|
||||
command like "make DESTDIR=... install". Read the *-install targets
|
||||
in the "Makefile" to understand how DESTDIR is used.
|
||||
|
||||
6. To set up a man.cgi(8) server, read its manual page.
|
||||
6. If you want to use the integrated man(1) and your system uses
|
||||
manpath(1), make sure it is configured correctly, in particular,
|
||||
it returns all directory trees where manual pages are installed.
|
||||
Otherwise, if your system uses man.conf(5), make sure it contains
|
||||
a "_whatdb" line for each directory tree, and the order of these
|
||||
lines meets your wishes.
|
||||
|
||||
7. To use mandoc(1) as your man(1) formatter, read the "Deployment"
|
||||
sections below.
|
||||
7. If you compiled with database support, run the command "sudo
|
||||
makewhatis" to build mandoc.db(5) databases in all the directory
|
||||
trees configured in step 6. Whenever installing new manual pages,
|
||||
re-run makewhatis(8) to update the databases, or apropos(1) will
|
||||
not find the new pages.
|
||||
|
||||
8. To set up a man.cgi(8) server, read its manual page.
|
||||
|
||||
Note that some man(7) pages may contain low-level roff(7) markup
|
||||
that mandoc does not yet understand. On some BSD systems using
|
||||
mandoc, third-party software is vetted on whether it may be formatted
|
||||
with mandoc. If not, groff(1) is pulled in as a dependency and
|
||||
used to install a pre-formatted "catpage" instead of directly as
|
||||
manual page source.
|
||||
|
||||
|
||||
Understanding mandoc dependencies
|
||||
---------------------------------
|
||||
The mandoc(1) and demandoc(1) utilities have no external dependencies.
|
||||
However, makewhatis(8), apropos(1), and man(1) depend on the following
|
||||
software:
|
||||
The mandoc(1), man(1), and demandoc(1) utilities have no external
|
||||
dependencies, but makewhatis(8) and apropos(1) depend on the
|
||||
following software:
|
||||
|
||||
1. The SQLite database system, see <http://sqlite.org/>.
|
||||
The recommended version of SQLite is 3.8.4.3 or newer. The mandoc
|
||||
@@ -142,76 +150,3 @@ for unexpected failures. Those are most likely to happen if headers
|
||||
or libraries are installed in unusual places or interfaces defined
|
||||
in unusual headers. You can also look at the file "config.h" and
|
||||
check that no "#define HAVE_*" differ from your expectations.
|
||||
|
||||
|
||||
Deployment using the integrated man(1) viewer
|
||||
---------------------------------------------
|
||||
This mode of deployment requires database support. In case of
|
||||
doubt, look at the section "user settings related to database
|
||||
support" in the file configure.local.example.
|
||||
|
||||
Deployment requires the following steps:
|
||||
|
||||
1. Build and install mandoc as described above in steps 2 to 5
|
||||
below "Installation".
|
||||
|
||||
2. If your system uses manpath(1), make sure it is configured
|
||||
correctly, in particular, it returns all directory trees where
|
||||
manual pages are installed. If your system uses man.conf(5), make
|
||||
sure it contains a "_whatdb" line for each directory tree, and the
|
||||
order of these lines meets your wishes.
|
||||
|
||||
3. Run the command "sudo makewhatis" to build mandoc.db(5) databases
|
||||
in all the directory trees configured in step 2.
|
||||
|
||||
At this point, your new man(1), apropos(1), and whatis(1) should work.
|
||||
Otherwise, please look at <http://mdocml.bsd.lv/contact.html>, both
|
||||
for help and to have these instructions improved.
|
||||
|
||||
Whenever installing new manual pages, re-run makewhatis(8) to update
|
||||
the databases, or man(1) will not find the new pages.
|
||||
|
||||
|
||||
Deployment using your system's native man(1) viewer
|
||||
---------------------------------------------------
|
||||
This mode of deployment does not require database support,
|
||||
so it works even if you don't have SQLite3.
|
||||
|
||||
Usually, you can have your default installation and mandoc(1) work right
|
||||
alongside each other by using user-specific versions of the files
|
||||
mentioned below.
|
||||
|
||||
0. Back up each file you want to change!
|
||||
|
||||
1. First see whether your system has "/etc/man.conf" or "/etc/manpath.conf"
|
||||
(if it has neither, but man(1) is functional, then let us know) or,
|
||||
if running as your own user, a per-user override file. In either
|
||||
case, find where man(1) is executing nroff(1) or groff(1) to format
|
||||
manuals. Replace these calls with mandoc(1).
|
||||
|
||||
2. Then make sure that man(1) isn't running preprocessors, so you may
|
||||
need to replace tbl(1), eqn(1), and similar references with cat(1).
|
||||
Some man(1) implementations, like that on Mac OSX, let you run "man -d"
|
||||
to see how the formatter is invoked. Use this to test your changes. On
|
||||
Mac OS X, for instance, man(1) will prepend all files with ".ll" and
|
||||
".nr" to set the terminal size, so you need to pass "tail -n+2 |
|
||||
mandoc(1)" to disregard them.
|
||||
|
||||
3. Finally, make sure that mandoc(1) is actually being invoked instead
|
||||
of cached pages being pulled up. You can usually do this by commenting
|
||||
out NOCACHE or similar.
|
||||
|
||||
|
||||
mandoc(1) still has a long way to go in understanding non-trivial
|
||||
low-level roff(7) markup embedded in some man(7) pages. On the BSD
|
||||
systems using mandoc(1), third-party software is generally vetted
|
||||
on whether it may be formatted with mandoc(1). If not, groff(1)
|
||||
is pulled in as a dependency and used to install a pre-formatted
|
||||
"catpage" instead of directly as manual page source.
|
||||
|
||||
For more background on switching operating systems to use mandoc(1)
|
||||
instead of groff(1) to format manuals, see the BSDCan and EuroBSDCon
|
||||
presentations by Ingo Schwarze:
|
||||
<http://www.openbsd.org/papers/bsdcan11-mandoc-openbsd.html>
|
||||
<http://www.openbsd.org/papers/bsdcan14-mandoc.pdf>
|
||||
<http://www.openbsd.org/papers/eurobsdcon2014-mandoc-paper.pdf>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# $Id: Makefile,v 1.456 2015/02/16 16:23:54 schwarze Exp $
|
||||
# $Id: Makefile,v 1.457 2015/03/13 12:35:32 schwarze Exp $
|
||||
#
|
||||
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
# Copyright (c) 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
# Copyright (c) 2011, 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -15,7 +15,7 @@
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
VERSION = 1.13.2
|
||||
VERSION = 1.13.3
|
||||
|
||||
# === LIST OF FILES ====================================================
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
BUILD_TARGETS = base-build
|
||||
INSTALL_TARGETS = base-install db-install
|
||||
CFLAGS = -g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings -I/usr/local/include
|
||||
DBLIB = -L/usr/local/lib -lsqlite3
|
||||
STATIC = -static
|
||||
PREFIX = /usr/local
|
||||
BINDIR = /usr/local/bin
|
||||
SBINDIR = /usr/local/sbin
|
||||
INCLUDEDIR = /usr/local/include/mandoc
|
||||
LIBDIR = /usr/local/lib/mandoc
|
||||
MANDIR = /usr/local/man
|
||||
EXAMPLEDIR = /usr/local/share/examples/mandoc
|
||||
WWWPREFIX = /var/www
|
||||
HTDOCDIR = /var/www/htdocs
|
||||
CGIBINDIR = /var/www/cgi-bin
|
||||
BINM_APROPOS = apropos
|
||||
BINM_MAN = man
|
||||
BINM_WHATIS = whatis
|
||||
BINM_MAKEWHATIS = makewhatis
|
||||
MANM_MAN = man
|
||||
MANM_MDOC = mdoc
|
||||
MANM_ROFF = roff
|
||||
MANM_EQN = eqn
|
||||
MANM_TBL = tbl
|
||||
INSTALL = install
|
||||
INSTALL_PROGRAM = install -m 0555
|
||||
INSTALL_LIB = install -m 0444
|
||||
INSTALL_MAN = install -m 0444
|
||||
INSTALL_DATA = install -m 0444
|
||||
MAIN_OBJS = $(BASE_OBJS) $(DB_OBJS)
|
||||
+116
-1
@@ -1,7 +1,122 @@
|
||||
$Id: NEWS,v 1.8 2014/12/13 13:43:47 schwarze Exp $
|
||||
$Id: NEWS,v 1.9 2015/03/13 12:35:32 schwarze Exp $
|
||||
|
||||
This file lists the most important changes in the mdocml.bsd.lv distribution.
|
||||
|
||||
Changes in version 1.13.3, released on March 13, 2015
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
* When a manual is missing from an outdated database, let man(1)
|
||||
show it anyway, using a KISS file system lookup as a fallback.
|
||||
* Use this to always provide man(1), even without database support.
|
||||
* Fatal errors no longer exist. If a file can be opened, mandoc
|
||||
will produce some output; at worst, the output may be almost empty.
|
||||
* New -Wunsupp message level.
|
||||
--- POTENTIONALLY SECURITY RELEVANT BUGFIXES ---
|
||||
* Fix a potential write buffer overrun on incomplete string conditionals.
|
||||
http://mdocml.bsd.lv/cgi-bin/cvsweb/roff.c#rev1.241
|
||||
* Fix a potential write buffer overrun on backslash at EOF in a conditional.
|
||||
http://mdocml.bsd.lv/cgi-bin/cvsweb/roff.c#rev1.247
|
||||
* Fix a use after free sometimes hit when validation deletes a block.
|
||||
http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_macro.c#rev1.180
|
||||
--- MAJOR FUNCTIONALLY RELEVANT BUGFIXES ---
|
||||
* Let man(1) show manuals for the current architecture by default,
|
||||
and support the MACHINE environment variable.
|
||||
* Fix the man(1) and apropos(1) -m option, it didn't work at all.
|
||||
* Do not spawn a pager when there is no output.
|
||||
* In makewhatis(8), fix detection of hardlinked manuals on platforms
|
||||
having padding in struct inodev (typically 64bit platforms).
|
||||
--- PORTABILITY IMPROVEMENTS ---
|
||||
* Ignore O_CLOEXEC when the operating system doesn't provide it.
|
||||
* Avoid forward reference to enum type which violates ISO C99.
|
||||
* Support homebrew-style linking on Mac OS X.
|
||||
--- MINOR NEW FEATURES ---
|
||||
* lookup: Accept digit+letter and "n" as section names in man(1),
|
||||
and consistently handle digit+letter in file name extensions.
|
||||
* lookup: Speed up -s/-S by using the "mlinks" rather than the "keys" table.
|
||||
* output: Insert horizontal lines between formatted manual pages.
|
||||
* input: New stricter and more resilient UTF-8 parser.
|
||||
* mdoc(7): Refactor block rewinding for simpler and more robust parsing.
|
||||
* man(7): Use the -Ios option when .TH has less than four arguments.
|
||||
* tbl(7): Implement the "center" option.
|
||||
* tbl(7): New option and format parsers, improved in many respects.
|
||||
* roff(7): Basic implementation of the \o escape sequence (overstrike),
|
||||
and improved rendering of overstrikes in PostScript and PDF output.
|
||||
* Message improvements, in particular for, but not restricted to,
|
||||
eqn(7), tbl(7), and wrong numbers of arguments in mdoc(7) and man(7),
|
||||
in various cases also improving output generated by invalid input.
|
||||
* Delete the -V option. It serves no purpose but keeps confusing people.
|
||||
* gmdiff: Minimal support for Heirloom roff.
|
||||
--- RELIABILITY BUGFIXES ---
|
||||
* tbl(7): Fix a read buffer overrun on 'f' at EOL in a layout.
|
||||
* roff(7): Fix a read buffer overrun on incomplete numerical conditions.
|
||||
* mdoc(7): Fix a NULL pointer access on .Nd followed by an explicit block.
|
||||
* mdoc(7): Fix a NULL pointer access on .It Xo without .Xc.
|
||||
* mdoc(7): Fix a NULL pointer access on .Eo without a tail.
|
||||
* mdoc(7): Fix a NULL pointer access in the validation of empty .St macros.
|
||||
* man(7)/tbl(7): Fix a NULL pointer access on .TS right after .TP.
|
||||
* tbl(7): Fix a NULL pointer access on layout lines without any cells.
|
||||
* eqn(7): Fix NULL pointer accesses in the terminal formatter.
|
||||
* roff(7): Fix a NULL pointer access on trailing \s-/\s+ without an argument.
|
||||
* gz: Fix a potential NULL pointer access after waitpid() failure.
|
||||
* roff(7): Don't let the modulo operator divide by zero.
|
||||
* input: Fix an assertion failure on certain invalid UTF-8 input.
|
||||
* terminal output: Allow arbitrary depth of the font stack (assertion fix).
|
||||
* mdoc(7): Fix assertion failures and endless loops on invalid block closing.
|
||||
* mdoc(7): Fix an assertion failure on .Bl .Sm not followed by .It.
|
||||
* mdoc(7): Fix an assertion failure on .Bl -column ... .El .Ta.
|
||||
* tbl(7): Fix assertion failures by macros inside table data,
|
||||
but do not throw away the macro arguments.
|
||||
* Prevent certain kinds of unreasonable input from producing excessive
|
||||
output, in one case caused by unsigned integer underflow.
|
||||
* Fix a potential memory leak in makewhatis(8) on very long filenames.
|
||||
--- MINOR BUGFIXES ---
|
||||
* mdoc(7): Fix parsing of badly nested blocks with multiple identical blocks.
|
||||
* mdoc(7): Support negative indentations for displays and lists.
|
||||
* mdoc(7): Don't mistreat negative .sp arguments as large positive ones.
|
||||
* mdoc(7): Some spacing fixes for .Eo/.Ec.
|
||||
* man(7): Support negative horizontal widths.
|
||||
* man(7): Do not print out invalid .IP arguments.
|
||||
* man(7): Correctly handle scaling units after .PD.
|
||||
* man(7): Support .RE with an argument.
|
||||
* man(7): Fix restoring indentation after .RS with large negative arguments.
|
||||
* tbl(7): Prevent tables from breaking the filling of preceding text.
|
||||
* tbl(7): Fix vertical spacing at the beginning of tables.
|
||||
* tbl(7): Parser and formatter fixes for line drawing and font modifiers.
|
||||
* tbl(7): Correct handling of blank data lines.
|
||||
* eqn(7): Add sometimes missing whitespace before equation output.
|
||||
* roff(7): Fix vertical scaling, most of it was wrong.
|
||||
* roff(7): Slightly improve \w width measurements.
|
||||
* roff(7): Accept the historic aliases \s10 to \s39 for \s(10 to \s(39.
|
||||
* roff(7): Correctly escape quotes when expanding macro arguments.
|
||||
* roff(7): Correctly handle scaling units in numerical expressions,
|
||||
and some other improvements to the parsing of numerical expressions.
|
||||
* roff(7): Three minor fixes with respect to evaluation of conditionals.
|
||||
* roff(7): Let .it accept numerical expressions, not just constants.
|
||||
* mandoc_char(7): Correct some character names and renderings.
|
||||
* If earlier files set a non-zero exit status, never reset it to zero.
|
||||
--- THANKS TO ---
|
||||
* Jonathan Gray (OpenBSD) for yet more testing with afl (the American
|
||||
Fuzzy Lop security fuzzer), again resulting in many bug reports.
|
||||
* Theo de Raadt (OpenBSD) for suggesting the main new feature (man(1) file
|
||||
system lookup) and for reporting an important bug (pager without output).
|
||||
* Theo Buehler for an important bug report (-s/-S slowness)
|
||||
and for proposing a nice new feature (lines between pages).
|
||||
* Jason McIntyre for an important bug report (hardlink detection)
|
||||
and multiple documentation patches.
|
||||
* Pascal Stumpf (OpenBSD) and Alessandro de Laurenzis for
|
||||
important bug reports (architecture and man -m, respectively).
|
||||
* Thomas Klausner (NetBSD) for proposing a new feature (man(7) -Ios),
|
||||
a bug report, and release testing.
|
||||
* Anthony Bentley, Daniel Dickman, Ted Unangst (OpenBSD) and
|
||||
Kristaps Dzonsons (bsd.lv) for source code patches and bug reports.
|
||||
* Christian Weisgerber (OpenBSD) for more than half a dozen bug reports.
|
||||
* Carsten Kunze (Heirloom troff) for bug reports and release testing.
|
||||
* Antoine Jacoutot (OpenBSD) for release testing.
|
||||
* Alexis Hildebrandt (Homebrew), Baptiste Daroussin (FreeBSD),
|
||||
Jonathan Perkin (SmartOS), Pedro Giffuni (FreeBSD), Svyatoslav
|
||||
Mishyn (Crux Linux), Ulrich Spoerlein (FreeBSD), Jan Stary, Patrick
|
||||
Keshishian, Sebastien Marie, and Steffen Nurpmeso for bug reports.
|
||||
|
||||
Changes in version 1.13.2, released on December 13, 2014
|
||||
|
||||
--- MAJOR NEW FEATURES ---
|
||||
|
||||
+6
-1
@@ -1,6 +1,6 @@
|
||||
************************************************************************
|
||||
* Official mandoc TODO.
|
||||
* $Id: TODO,v 1.201 2015/02/20 13:47:28 schwarze Exp $
|
||||
* $Id: TODO,v 1.202 2015/03/11 13:11:22 schwarze Exp $
|
||||
************************************************************************
|
||||
|
||||
Many issues are annotated for difficulty as follows:
|
||||
@@ -557,6 +557,11 @@ Several areas can be cleaned up to make mandoc even faster. These are
|
||||
* structural issues
|
||||
************************************************************************
|
||||
|
||||
- Improve -O suboption parsing. Do it in the main program such that
|
||||
errors can be reported. Pay attention to distinguishing the
|
||||
mandoc(1) and apropos(1) styles of both options.
|
||||
loc ** exist * algo ** size ** imp ***
|
||||
|
||||
- Use libz directly instead of forking gunzip(1).
|
||||
Suggested by bapt at FreeBSD among others.
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define VERSION "1.13.2"
|
||||
#define HAVE_DIRENT_NAMLEN 1
|
||||
#define HAVE_FGETLN 1
|
||||
#define HAVE_FTS 1
|
||||
|
||||
Vendored
+1
-3
@@ -237,9 +237,7 @@ elif [ -z "${DBLIB}" ]; then
|
||||
fi
|
||||
|
||||
# --- manpath ---
|
||||
if [ ${BUILD_DB} -eq 0 ]; then
|
||||
HAVE_MANPATH=0
|
||||
elif ismanual manpath "${HAVE_MANPATH}"; then
|
||||
if ismanual manpath "${HAVE_MANPATH}"; then
|
||||
:
|
||||
elif manpath 1>&3 2>&3; then
|
||||
echo "manpath: yes" 1>&2
|
||||
|
||||
+24
-24
@@ -1,4 +1,4 @@
|
||||
.\" $Id: eqn.7,v 1.33 2015/01/29 00:33:57 schwarze Exp $
|
||||
.\" $Id: eqn.7,v 1.34 2015/03/09 20:17:23 schwarze Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: January 29 2015 $
|
||||
.Dd $Mdocdate: March 9 2015 $
|
||||
.Dt EQN 7
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -72,31 +72,31 @@ case-sensitive literals in the input:
|
||||
.Bd -literal -offset indent
|
||||
eqn : box | eqn box
|
||||
box : text
|
||||
| \*q{\*q eqn \*q}\*q
|
||||
| \*qdefine\*q text text
|
||||
| \*qndefine\*q text text
|
||||
| \*qtdefine\*q text text
|
||||
| \*qgfont\*q text
|
||||
| \*qgsize\*q text
|
||||
| \*qset\*q text text
|
||||
| \*qundef\*q text
|
||||
| \*qsqrt\*q box
|
||||
| \(dq{\(dq eqn \(dq}\(dq
|
||||
| \(dqdefine\(dq text text
|
||||
| \(dqndefine\(dq text text
|
||||
| \(dqtdefine\(dq text text
|
||||
| \(dqgfont\(dq text
|
||||
| \(dqgsize\(dq text
|
||||
| \(dqset\(dq text text
|
||||
| \(dqundef\(dq text
|
||||
| \(dqsqrt\(dq box
|
||||
| box pos box
|
||||
| box mark
|
||||
| \*qmatrix\*q \*q{\*q [col \*q{\*q list \*q}\*q ]*
|
||||
| pile \*q{\*q list \*q}\*q
|
||||
| \(dqmatrix\(dq \(dq{\(dq [col \(dq{\(dq list \(dq}\(dq ]*
|
||||
| pile \(dq{\(dq list \(dq}\(dq
|
||||
| font box
|
||||
| \*qsize\*q text box
|
||||
| \*qleft\*q text eqn [\*qright\*q text]
|
||||
col : \*qlcol\*q | \*qrcol\*q | \*qccol\*q | \*qcol\*q
|
||||
text : [^space\e\*q]+ | \e\*q.*\e\*q
|
||||
pile : \*qlpile\*q | \*qcpile\*q | \*qrpile\*q | \*qpile\*q
|
||||
pos : \*qover\*q | \*qsup\*q | \*qsub\*q | \*qto\*q | \*qfrom\*q
|
||||
mark : \*qdot\*q | \*qdotdot\*q | \*qhat\*q | \*qtilde\*q | \*qvec\*q
|
||||
| \*qdyad\*q | \*qbar\*q | \*qunder\*q
|
||||
font : \*qroman\*q | \*qitalic\*q | \*qbold\*q | \*qfat\*q
|
||||
| \(dqsize\(dq text box
|
||||
| \(dqleft\(dq text eqn [\(dqright\(dq text]
|
||||
col : \(dqlcol\(dq | \(dqrcol\(dq | \(dqccol\(dq | \(dqcol\(dq
|
||||
text : [^space\e\(dq]+ | \e\(dq.*\e\(dq
|
||||
pile : \(dqlpile\(dq | \(dqcpile\(dq | \(dqrpile\(dq | \(dqpile\(dq
|
||||
pos : \(dqover\(dq | \(dqsup\(dq | \(dqsub\(dq | \(dqto\(dq | \(dqfrom\(dq
|
||||
mark : \(dqdot\(dq | \(dqdotdot\(dq | \(dqhat\(dq | \(dqtilde\(dq | \(dqvec\(dq
|
||||
| \(dqdyad\(dq | \(dqbar\(dq | \(dqunder\(dq
|
||||
font : \(dqroman\(dq | \(dqitalic\(dq | \(dqbold\(dq | \(dqfat\(dq
|
||||
list : eqn
|
||||
| list \*qabove\*q eqn
|
||||
| list \(dqabove\(dq eqn
|
||||
space : [\e^~ \et]
|
||||
.Ed
|
||||
.Pp
|
||||
@@ -434,7 +434,7 @@ implementation (including GNU troff).
|
||||
.Bl -dash -compact
|
||||
.It
|
||||
The text string
|
||||
.Sq \e\*q
|
||||
.Sq \e\(dq
|
||||
is interpreted as a literal quote in troff.
|
||||
In mandoc, this is interpreted as a comment.
|
||||
.It
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: eqn.c,v 1.57 2015/01/28 21:11:53 schwarze Exp $ */
|
||||
/* $Id: eqn.c,v 1.58 2015/03/04 12:19:49 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -194,6 +194,7 @@ enum eqn_symt {
|
||||
EQNSYM_equiv,
|
||||
EQNSYM_lessequal,
|
||||
EQNSYM_moreequal,
|
||||
EQNSYM_minus,
|
||||
EQNSYM__MAX
|
||||
};
|
||||
|
||||
@@ -249,7 +250,7 @@ static const struct eqnsym eqnsyms[EQNSYM__MAX] = {
|
||||
{ "cdot", "pc" }, /* EQNSYM_cdot */
|
||||
{ "nothing", "&" }, /* EQNSYM_nothing */
|
||||
{ "approx", "~~" }, /* EQNSYM_approx */
|
||||
{ "prime", "aq" }, /* EQNSYM_prime */
|
||||
{ "prime", "fm" }, /* EQNSYM_prime */
|
||||
{ "half", "12" }, /* EQNSYM_half */
|
||||
{ "partial", "pd" }, /* EQNSYM_partial */
|
||||
{ "inf", "if" }, /* EQNSYM_inf */
|
||||
@@ -262,6 +263,7 @@ static const struct eqnsym eqnsyms[EQNSYM__MAX] = {
|
||||
{ "==", "==" }, /* EQNSYM_equiv */
|
||||
{ "<=", "<=" }, /* EQNSYM_lessequal */
|
||||
{ ">=", ">=" }, /* EQNSYM_moreequal */
|
||||
{ "-", "mi" }, /* EQNSYM_minus */
|
||||
};
|
||||
|
||||
static struct eqn_box *eqn_box_alloc(struct eqn_node *, struct eqn_box *);
|
||||
|
||||
+37
-21
@@ -1,4 +1,4 @@
|
||||
/* $Id: main.c,v 1.222 2015/02/27 16:02:10 schwarze Exp $ */
|
||||
/* $Id: main.c,v 1.225 2015/03/10 13:50:03 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h> /* MACHINE */
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
@@ -101,7 +102,7 @@ static void mmsg(enum mandocerr, enum mandoclevel,
|
||||
static void parse(struct curparse *, int,
|
||||
const char *, enum mandoclevel *);
|
||||
static enum mandoclevel passthrough(const char *, int, int);
|
||||
static void spawn_pager(void);
|
||||
static pid_t spawn_pager(void);
|
||||
static int toptions(struct curparse *, char *);
|
||||
static void usage(enum argmode) __attribute__((noreturn));
|
||||
static int woptions(struct curparse *, char *);
|
||||
@@ -130,9 +131,9 @@ main(int argc, char *argv[])
|
||||
enum outmode outmode;
|
||||
int fd;
|
||||
int show_usage;
|
||||
int use_pager;
|
||||
int options;
|
||||
int c;
|
||||
pid_t pager_pid; /* 0: don't use; 1: not yet spawned. */
|
||||
|
||||
if (argc < 1)
|
||||
progname = "mandoc";
|
||||
@@ -174,7 +175,7 @@ main(int argc, char *argv[])
|
||||
options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1;
|
||||
defos = NULL;
|
||||
|
||||
use_pager = 1;
|
||||
pager_pid = 1;
|
||||
show_usage = 0;
|
||||
synopsis_only = 0;
|
||||
outmode = OUTMODE_DEF;
|
||||
@@ -189,7 +190,7 @@ main(int argc, char *argv[])
|
||||
conf_file = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
use_pager = 0;
|
||||
pager_pid = 0;
|
||||
break;
|
||||
case 'f':
|
||||
search.argmode = ARG_WORD;
|
||||
@@ -197,7 +198,7 @@ main(int argc, char *argv[])
|
||||
case 'h':
|
||||
(void)strlcat(curp.outopts, "synopsis,", BUFSIZ);
|
||||
synopsis_only = 1;
|
||||
use_pager = 0;
|
||||
pager_pid = 0;
|
||||
outmode = OUTMODE_ALL;
|
||||
break;
|
||||
case 'I':
|
||||
@@ -272,7 +273,7 @@ main(int argc, char *argv[])
|
||||
switch (search.argmode) {
|
||||
case ARG_FILE:
|
||||
outmode = OUTMODE_ALL;
|
||||
use_pager = 0;
|
||||
pager_pid = 0;
|
||||
break;
|
||||
case ARG_NAME:
|
||||
outmode = OUTMODE_ONE;
|
||||
@@ -303,18 +304,20 @@ main(int argc, char *argv[])
|
||||
argc = 1;
|
||||
}
|
||||
} else if (argc > 1 &&
|
||||
((uc = argv[0]) != NULL) &&
|
||||
((uc = (unsigned char *)argv[0]) != NULL) &&
|
||||
((isdigit(uc[0]) && (uc[1] == '\0' ||
|
||||
(isalpha(uc[1]) && uc[2] == '\0'))) ||
|
||||
(uc[0] == 'n' && uc[1] == '\0'))) {
|
||||
search.sec = uc;
|
||||
search.sec = (char *)uc;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
if (search.arch == NULL)
|
||||
search.arch = getenv("MACHINE");
|
||||
#ifdef MACHINE
|
||||
if (search.arch == NULL)
|
||||
search.arch = MACHINE;
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = MANDOCLEVEL_OK;
|
||||
@@ -415,8 +418,8 @@ main(int argc, char *argv[])
|
||||
mparse_keep(curp.mp);
|
||||
|
||||
if (argc < 1) {
|
||||
if (use_pager && isatty(STDOUT_FILENO))
|
||||
spawn_pager();
|
||||
if (pager_pid == 1 && isatty(STDOUT_FILENO))
|
||||
pager_pid = spawn_pager();
|
||||
parse(&curp, STDIN_FILENO, "<stdin>", &rc);
|
||||
}
|
||||
|
||||
@@ -427,9 +430,8 @@ main(int argc, char *argv[])
|
||||
rc = rctmp;
|
||||
|
||||
if (fd != -1) {
|
||||
if (use_pager && isatty(STDOUT_FILENO))
|
||||
spawn_pager();
|
||||
use_pager = 0;
|
||||
if (pager_pid == 1 && isatty(STDOUT_FILENO))
|
||||
pager_pid = spawn_pager();
|
||||
|
||||
if (resp == NULL)
|
||||
parse(&curp, fd, *argv, &rc);
|
||||
@@ -479,6 +481,17 @@ main(int argc, char *argv[])
|
||||
|
||||
free(defos);
|
||||
|
||||
/*
|
||||
* If a pager is attached, flush the pipe leading to it
|
||||
* and signal end of file such that the user can browse
|
||||
* to the end. Then wait for the user to close the pager.
|
||||
*/
|
||||
|
||||
if (pager_pid != 0 && pager_pid != 1) {
|
||||
fclose(stdout);
|
||||
waitpid(pager_pid, NULL, 0);
|
||||
}
|
||||
|
||||
return((int)rc);
|
||||
}
|
||||
|
||||
@@ -927,7 +940,7 @@ mmsg(enum mandocerr t, enum mandoclevel lvl,
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
static void
|
||||
static pid_t
|
||||
spawn_pager(void)
|
||||
{
|
||||
#define MAX_PAGER_ARGS 16
|
||||
@@ -936,31 +949,33 @@ spawn_pager(void)
|
||||
char *cp;
|
||||
int fildes[2];
|
||||
int argc;
|
||||
pid_t pager_pid;
|
||||
|
||||
if (pipe(fildes) == -1) {
|
||||
fprintf(stderr, "%s: pipe: %s\n",
|
||||
progname, strerror(errno));
|
||||
return;
|
||||
return(0);
|
||||
}
|
||||
|
||||
switch (fork()) {
|
||||
switch (pager_pid = fork()) {
|
||||
case -1:
|
||||
fprintf(stderr, "%s: fork: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
close(fildes[0]);
|
||||
if (dup2(fildes[1], STDOUT_FILENO) == -1) {
|
||||
fprintf(stderr, "%s: dup output: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
close(fildes[1]);
|
||||
return(pager_pid);
|
||||
}
|
||||
|
||||
/* The original process becomes the pager. */
|
||||
/* The child process becomes the pager. */
|
||||
|
||||
close(fildes[1]);
|
||||
if (dup2(fildes[0], STDIN_FILENO) == -1) {
|
||||
@@ -968,6 +983,7 @@ spawn_pager(void)
|
||||
progname, strerror(errno));
|
||||
exit((int)MANDOCLEVEL_SYSERR);
|
||||
}
|
||||
close(fildes[0]);
|
||||
|
||||
pager = getenv("MANPAGER");
|
||||
if (pager == NULL || *pager == '\0')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: man_html.c,v 1.111 2015/02/10 08:05:30 schwarze Exp $ */
|
||||
/* $Id: man_html.c,v 1.112 2015/03/03 21:11:34 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -223,6 +223,8 @@ print_man_node(MAN_ARGS)
|
||||
print_text(h, n->string);
|
||||
return;
|
||||
case MAN_EQN:
|
||||
if (n->flags & MAN_LINE)
|
||||
putchar('\n');
|
||||
print_eqn(h, n->eqn);
|
||||
break;
|
||||
case MAN_TBL:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: man_term.c,v 1.168 2015/01/30 22:04:44 schwarze Exp $ */
|
||||
/* $Id: man_term.c,v 1.169 2015/03/06 15:48:52 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -945,12 +945,8 @@ print_man_node(DECL_ARGS)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
return;
|
||||
case MAN_TBL:
|
||||
/*
|
||||
* Tables are preceded by a newline. Then process a
|
||||
* table line, which will cause line termination,
|
||||
*/
|
||||
if (n->span->prev == NULL)
|
||||
term_newln(p);
|
||||
if (p->tbl.cols == NULL)
|
||||
term_vspace(p);
|
||||
term_tbl(p, n->span);
|
||||
return;
|
||||
default:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: mandocdb.c,v 1.185 2015/02/27 16:22:09 schwarze Exp $ */
|
||||
/* $Id: mandocdb.c,v 1.186 2015/03/13 00:19:41 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -942,6 +942,7 @@ mlink_add(struct mlink *mlink, const struct stat *st)
|
||||
assert(NULL == ohash_find(&mlinks, slot));
|
||||
ohash_insert(&mlinks, slot, mlink);
|
||||
|
||||
memset(&inodev, 0, sizeof(inodev)); /* Clear padding. */
|
||||
inodev.st_ino = st->st_ino;
|
||||
inodev.st_dev = st->st_dev;
|
||||
slot = ohash_lookup_memory(&mpages, (char *)&inodev,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: mansearch.c,v 1.54 2015/02/27 16:02:10 schwarze Exp $ */
|
||||
/* $Id: mansearch.c,v 1.55 2015/03/11 13:11:22 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -195,8 +195,8 @@ mansearch(const struct mansearch *search,
|
||||
if (NULL == (e = exprcomp(search, argc, argv)))
|
||||
goto out;
|
||||
|
||||
outbit = 0;
|
||||
if (NULL != search->outkey) {
|
||||
outbit = TYPE_Nd;
|
||||
for (indexbit = 0, iterbit = 1;
|
||||
indexbit < mansearch_keymax;
|
||||
indexbit++, iterbit <<= 1) {
|
||||
@@ -206,7 +206,8 @@ mansearch(const struct mansearch *search,
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
outbit = 0;
|
||||
|
||||
/*
|
||||
* Save a descriptor to the current working directory.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_html.c,v 1.225 2015/02/12 12:24:33 schwarze Exp $ */
|
||||
/* $Id: mdoc_html.c,v 1.226 2015/03/03 21:11:34 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -411,6 +411,8 @@ print_mdoc_node(MDOC_ARGS)
|
||||
h->flags |= HTML_NOSPACE;
|
||||
return;
|
||||
case MDOC_EQN:
|
||||
if (n->flags & MDOC_LINE)
|
||||
putchar('\n');
|
||||
print_eqn(h, n->eqn);
|
||||
break;
|
||||
case MDOC_TBL:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: mdoc_term.c,v 1.311 2015/02/17 20:37:17 schwarze Exp $ */
|
||||
/* $Id: mdoc_term.c,v 1.313 2015/03/06 15:48:52 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -348,6 +348,8 @@ print_mdoc_node(DECL_ARGS)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
break;
|
||||
case MDOC_TBL:
|
||||
if (p->tbl.cols == NULL)
|
||||
term_newln(p);
|
||||
term_tbl(p, n->span);
|
||||
break;
|
||||
default:
|
||||
@@ -1808,7 +1810,7 @@ static int
|
||||
termp_sp_pre(DECL_ARGS)
|
||||
{
|
||||
struct roffsu su;
|
||||
size_t i, len;
|
||||
int i, len;
|
||||
|
||||
switch (n->tok) {
|
||||
case MDOC_sp:
|
||||
@@ -1829,8 +1831,11 @@ termp_sp_pre(DECL_ARGS)
|
||||
|
||||
if (0 == len)
|
||||
term_newln(p);
|
||||
for (i = 0; i < len; i++)
|
||||
term_vspace(p);
|
||||
else if (len < 0)
|
||||
p->skipvsp -= len;
|
||||
else
|
||||
for (i = 0; i < len; i++)
|
||||
term_vspace(p);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: preconv.c,v 1.13 2014/12/19 04:58:35 schwarze Exp $ */
|
||||
/* $Id: preconv.c,v 1.14 2015/03/06 09:24:59 kristaps Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -33,7 +33,7 @@ preconv_encode(struct buf *ib, size_t *ii, struct buf *ob, size_t *oi,
|
||||
int nby;
|
||||
unsigned int accum;
|
||||
|
||||
cu = ib->buf + *ii;
|
||||
cu = (unsigned char *)ib->buf + *ii;
|
||||
assert(*cu & 0x80);
|
||||
|
||||
if ( ! (*filenc & MPARSE_UTF8))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: read.c,v 1.129 2015/03/02 14:50:17 schwarze Exp $ */
|
||||
/* $Id: read.c,v 1.131 2015/03/11 13:05:20 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -636,7 +636,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd,
|
||||
*/
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
if (st.st_size >= (1U << 31)) {
|
||||
if (st.st_size > 0x7fffffff) {
|
||||
mandoc_msg(MANDOCERR_TOOLARGE, curp, 0, 0, NULL);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: tbl_term.c,v 1.38 2015/01/31 00:12:41 schwarze Exp $ */
|
||||
/* $Id: tbl_term.c,v 1.40 2015/03/06 15:48:53 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2011, 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -82,8 +82,6 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
|
||||
*/
|
||||
|
||||
if (tp->tbl.cols == NULL) {
|
||||
term_flushln(tp);
|
||||
|
||||
tp->tbl.len = term_tbl_len;
|
||||
tp->tbl.slen = term_tbl_strlen;
|
||||
tp->tbl.arg = tp;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: term.c,v 1.244 2015/01/31 00:12:41 schwarze Exp $ */
|
||||
/* $Id: term.c,v 1.245 2015/03/06 13:02:43 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
* Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
|
||||
@@ -413,6 +413,7 @@ term_word(struct termp *p, const char *word)
|
||||
p->flags |= TERMP_NOSPACE;
|
||||
|
||||
p->flags &= ~(TERMP_SENTENCE | TERMP_NONEWLINE);
|
||||
p->skipvsp = 0;
|
||||
|
||||
while ('\0' != *word) {
|
||||
if ('\\' != *word) {
|
||||
|
||||
@@ -2775,8 +2775,12 @@ zvol_geom_worker(void *arg)
|
||||
break;
|
||||
case BIO_READ:
|
||||
case BIO_WRITE:
|
||||
case BIO_DELETE:
|
||||
zvol_strategy(bp);
|
||||
break;
|
||||
default:
|
||||
g_io_deliver(bp, EOPNOTSUPP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/sx.h>
|
||||
|
||||
#include <cam/cam.h>
|
||||
@@ -586,14 +587,15 @@ isc_dump_options(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error;
|
||||
isc_session_t *sp;
|
||||
char buf[1024], *bp;
|
||||
struct sbuf sb;
|
||||
|
||||
sbuf_new_for_sysctl(&sb, NULL, 128, req);
|
||||
|
||||
sp = (isc_session_t *)arg1;
|
||||
bp = buf;
|
||||
sprintf(bp, "targetname='%s'", sp->opt.targetName);
|
||||
bp += strlen(bp);
|
||||
sprintf(bp, " targetname='%s'", sp->opt.targetAddress);
|
||||
error = SYSCTL_OUT(req, buf, strlen(buf));
|
||||
sbuf_printf(&sb, "targetname='%s'", sp->opt.targetName);
|
||||
sbuf_printf(&sb, " targetaddress='%s'", sp->opt.targetAddress);
|
||||
error = sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
@@ -603,51 +605,24 @@ isc_dump_stats(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
isc_session_t *sp;
|
||||
struct isc_softc *sc;
|
||||
char buf[1024], *bp;
|
||||
int error, n;
|
||||
|
||||
int error;
|
||||
struct sbuf sb;
|
||||
|
||||
sp = (isc_session_t *)arg1;
|
||||
sc = sp->isc;
|
||||
|
||||
bp = buf;
|
||||
n = sizeof(buf);
|
||||
snprintf(bp, n, "recv=%d sent=%d", sp->stats.nrecv, sp->stats.nsent);
|
||||
bp += strlen(bp);
|
||||
n -= strlen(bp);
|
||||
snprintf(bp, n, " flags=0x%08x pdus-alloc=%d pdus-max=%d",
|
||||
sp->flags, sc->npdu_alloc, sc->npdu_max);
|
||||
bp += strlen(bp);
|
||||
n -= strlen(bp);
|
||||
snprintf(bp, n, " cws=%d cmd=%x exp=%x max=%x stat=%x itt=%x",
|
||||
sbuf_new_for_sysctl(&sb, NULL, 128, req);
|
||||
|
||||
sbuf_printf(&sb, "recv=%d sent=%d", sp->stats.nrecv, sp->stats.nsent);
|
||||
sbuf_printf(&sb, " flags=0x%08x pdus-alloc=%d pdus-max=%d",
|
||||
sp->flags, sc->npdu_alloc, sc->npdu_max);
|
||||
sbuf_printf(&sb, " cws=%d cmd=%x exp=%x max=%x stat=%x itt=%x",
|
||||
sp->cws, sp->sn.cmd, sp->sn.expCmd, sp->sn.maxCmd, sp->sn.stat, sp->sn.itt);
|
||||
error = SYSCTL_OUT(req, buf, strlen(buf));
|
||||
error = sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
isc_sysctl_targetName(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
char buf[128], **cp;
|
||||
int error;
|
||||
|
||||
cp = (char **)arg1;
|
||||
snprintf(buf, sizeof(buf), "%s", *cp);
|
||||
error = SYSCTL_OUT(req, buf, strlen(buf));
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
isc_sysctl_targetAddress(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
char buf[128], **cp;
|
||||
int error;
|
||||
|
||||
cp = (char **)arg1;
|
||||
snprintf(buf, sizeof(buf), "%s", *cp);
|
||||
error = SYSCTL_OUT(req, buf, strlen(buf));
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
isc_add_sysctls(isc_session_t *sp)
|
||||
{
|
||||
@@ -668,7 +643,7 @@ isc_add_sysctls(isc_session_t *sp)
|
||||
"targetname",
|
||||
CTLTYPE_STRING | CTLFLAG_RD,
|
||||
(void *)&sp->opt.targetName, 0,
|
||||
isc_sysctl_targetName, "A", "target name");
|
||||
sysctl_handle_string, "A", "target name");
|
||||
|
||||
SYSCTL_ADD_PROC(&sp->clist,
|
||||
SYSCTL_CHILDREN(sp->oid),
|
||||
@@ -676,7 +651,7 @@ isc_add_sysctls(isc_session_t *sp)
|
||||
"targeaddress",
|
||||
CTLTYPE_STRING | CTLFLAG_RD,
|
||||
(void *)&sp->opt.targetAddress, 0,
|
||||
isc_sysctl_targetAddress, "A", "target address");
|
||||
sysctl_handle_string, "A", "target address");
|
||||
|
||||
SYSCTL_ADD_PROC(&sp->clist,
|
||||
SYSCTL_CHILDREN(sp->oid),
|
||||
|
||||
@@ -155,7 +155,7 @@ ue_sysctl_parent(SYSCTL_HANDLER_ARGS)
|
||||
const char *name;
|
||||
|
||||
name = device_get_nameunit(ue->ue_dev);
|
||||
return SYSCTL_OUT(req, name, strlen(name));
|
||||
return SYSCTL_OUT_STR(req, name);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -292,7 +292,8 @@ sysctl_kern_console(SYSCTL_HANDLER_ARGS)
|
||||
int delete, error;
|
||||
struct sbuf *sb;
|
||||
|
||||
sb = sbuf_new(NULL, NULL, CNDEVPATHMAX * 2, SBUF_AUTOEXTEND);
|
||||
sb = sbuf_new(NULL, NULL, CNDEVPATHMAX * 2, SBUF_AUTOEXTEND |
|
||||
SBUF_INCLUDENUL);
|
||||
if (sb == NULL)
|
||||
return (ENOMEM);
|
||||
sbuf_clear(sb);
|
||||
|
||||
+13
-10
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/queue.h>
|
||||
@@ -238,22 +239,24 @@ et_free(struct eventtimer *et)
|
||||
static int
|
||||
sysctl_kern_eventtimer_choice(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
char buf[512], *spc;
|
||||
struct sbuf sb;
|
||||
struct eventtimer *et;
|
||||
int error, off;
|
||||
int error;
|
||||
|
||||
if ((error = sysctl_wire_old_buffer(req, 0)) != 0)
|
||||
return (error);
|
||||
sbuf_new_for_sysctl(&sb, NULL, 0, req);
|
||||
|
||||
spc = "";
|
||||
error = 0;
|
||||
buf[0] = 0;
|
||||
off = 0;
|
||||
ET_LOCK();
|
||||
SLIST_FOREACH(et, &eventtimers, et_all) {
|
||||
off += snprintf(buf + off, sizeof(buf) - off, "%s%s(%d)",
|
||||
spc, et->et_name, et->et_quality);
|
||||
spc = " ";
|
||||
if (et != SLIST_FIRST(&eventtimers))
|
||||
sbuf_putc(&sb, ' ');
|
||||
sbuf_printf(&sb, "%s(%d)", et->et_name, et->et_quality);
|
||||
}
|
||||
ET_UNLOCK();
|
||||
error = SYSCTL_OUT(req, buf, strlen(buf));
|
||||
|
||||
error = sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
return (error);
|
||||
}
|
||||
SYSCTL_PROC(_kern_eventtimer, OID_AUTO, choice,
|
||||
|
||||
@@ -394,11 +394,10 @@ fail_point_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
int error;
|
||||
|
||||
/* Retrieving */
|
||||
sbuf_new(&sb, NULL, 128, SBUF_AUTOEXTEND);
|
||||
sbuf_new_for_sysctl(&sb, NULL, 128, req);
|
||||
fail_point_get(fp, &sb);
|
||||
sbuf_trim(&sb);
|
||||
sbuf_finish(&sb);
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
|
||||
error = sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
|
||||
/* Setting */
|
||||
|
||||
+9
-8
@@ -25,6 +25,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/limits.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
@@ -1445,18 +1446,18 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW,
|
||||
static int
|
||||
sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
char buf[32], *spc;
|
||||
struct sbuf sb;
|
||||
struct timecounter *tc;
|
||||
int error;
|
||||
|
||||
spc = "";
|
||||
error = 0;
|
||||
for (tc = timecounters; error == 0 && tc != NULL; tc = tc->tc_next) {
|
||||
sprintf(buf, "%s%s(%d)",
|
||||
spc, tc->tc_name, tc->tc_quality);
|
||||
error = SYSCTL_OUT(req, buf, strlen(buf));
|
||||
spc = " ";
|
||||
sbuf_new_for_sysctl(&sb, NULL, 0, req);
|
||||
for (tc = timecounters; tc != NULL; tc = tc->tc_next) {
|
||||
if (tc != timecounters)
|
||||
sbuf_putc(&sb, ' ');
|
||||
sbuf_printf(&sb, "%s(%d)", tc->tc_name, tc->tc_quality);
|
||||
}
|
||||
error = sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
@@ -2830,7 +2830,7 @@ sysctl_kern_sched_topology_spec(SYSCTL_HANDLER_ARGS)
|
||||
|
||||
KASSERT(cpu_top != NULL, ("cpu_top isn't initialized"));
|
||||
|
||||
topo = sbuf_new(NULL, NULL, 500, SBUF_AUTOEXTEND);
|
||||
topo = sbuf_new_for_sysctl(NULL, NULL, 512, req);
|
||||
if (topo == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
@@ -2839,8 +2839,7 @@ sysctl_kern_sched_topology_spec(SYSCTL_HANDLER_ARGS)
|
||||
sbuf_printf(topo, "</groups>\n");
|
||||
|
||||
if (err == 0) {
|
||||
sbuf_finish(topo);
|
||||
err = SYSCTL_OUT(req, sbuf_data(topo), sbuf_len(topo));
|
||||
err = sbuf_finish(topo);
|
||||
}
|
||||
sbuf_delete(topo);
|
||||
return (err);
|
||||
|
||||
+2
-2
@@ -212,7 +212,7 @@ devclass_sysctl_handler(SYSCTL_HANDLER_ARGS)
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
return (SYSCTL_OUT(req, value, strlen(value)));
|
||||
return (SYSCTL_OUT_STR(req, value));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -269,7 +269,7 @@ device_sysctl_handler(SYSCTL_HANDLER_ARGS)
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
error = SYSCTL_OUT(req, value, strlen(value));
|
||||
error = SYSCTL_OUT_STR(req, value);
|
||||
if (buf != NULL)
|
||||
free(buf, M_BUS);
|
||||
return (error);
|
||||
|
||||
@@ -300,6 +300,5 @@ init_param2(long physpages)
|
||||
static int
|
||||
sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
return (SYSCTL_OUT(req, vm_guest_sysctl_names[vm_guest],
|
||||
strlen(vm_guest_sysctl_names[vm_guest])));
|
||||
return (SYSCTL_OUT_STR(req, vm_guest_sysctl_names[vm_guest]));
|
||||
}
|
||||
|
||||
+1
-1
@@ -1009,7 +1009,7 @@ sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
|
||||
len = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq);
|
||||
mtx_unlock(&msgbuf_lock);
|
||||
if (len == 0)
|
||||
return (0);
|
||||
return (SYSCTL_OUT(req, "", 1)); /* add nulterm */
|
||||
|
||||
error = sysctl_handle_opaque(oidp, buf, len, req);
|
||||
if (error)
|
||||
|
||||
+8
-12
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/proc.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/sbuf.h>
|
||||
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/kernel.h>
|
||||
@@ -473,27 +474,22 @@ SYSINIT(start_msgring_threads, SI_SUB_SMP, SI_ORDER_MIDDLE,
|
||||
static int
|
||||
sys_print_debug(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error, nb, i, fs;
|
||||
static char xprintb[4096], *buf;
|
||||
struct sbuf sb;
|
||||
int error, i;
|
||||
|
||||
buf = xprintb;
|
||||
fs = sizeof(xprintb);
|
||||
nb = snprintf(buf, fs,
|
||||
sbuf_new_for_sysctl(&sb, NULL, 64, req);
|
||||
sbuf_printf(&sb,
|
||||
"\nID vc0 vc1 vc2 vc3 loops\n");
|
||||
buf += nb;
|
||||
fs -= nb;
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((xlp_hw_thread_mask & (1 << i)) == 0)
|
||||
continue;
|
||||
nb = snprintf(buf, fs,
|
||||
"%2d: %8d %8d %8d %8d %8d\n", i,
|
||||
sbuf_printf(&sb, "%2d: %8d %8d %8d %8d %8d\n", i,
|
||||
fmn_msgcount[i][0], fmn_msgcount[i][1],
|
||||
fmn_msgcount[i][2], fmn_msgcount[i][3],
|
||||
fmn_loops[i]);
|
||||
buf += nb;
|
||||
fs -= nb;
|
||||
}
|
||||
error = SYSCTL_OUT(req, xprintb, buf - xprintb);
|
||||
error = sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ at24co2n_mac_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
p = sc->sc_mac_addr;
|
||||
len = snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
return SYSCTL_OUT(req, buf, len);
|
||||
return SYSCTL_OUT_STR(req, buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-12
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/proc.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/sbuf.h>
|
||||
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/kernel.h>
|
||||
@@ -468,27 +469,22 @@ SYSINIT(start_msgring_threads, SI_SUB_SMP, SI_ORDER_MIDDLE,
|
||||
static int
|
||||
sys_print_debug(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error, nb, i, fs;
|
||||
static char xprintb[4096], *buf;
|
||||
struct sbuf sb;
|
||||
int error, i;
|
||||
|
||||
buf = xprintb;
|
||||
fs = sizeof(xprintb);
|
||||
nb = snprintf(buf, fs,
|
||||
sbuf_new_for_sysctl(&sb, NULL, 64, req);
|
||||
sbuf_printf(&sb,
|
||||
"\nID INTR ER WU-SLP WU-ERR MSGS\n");
|
||||
buf += nb;
|
||||
fs -= nb;
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((xlr_hw_thread_mask & (1 << i)) == 0)
|
||||
continue;
|
||||
nb = snprintf(buf, fs,
|
||||
"%2d: %8d %4d %8d %8d %8d\n", i,
|
||||
sbuf_printf(&sb, "%2d: %8d %4d %8d %8d %8d\n", i,
|
||||
msgring_nintr[i/4], msgring_badintr[i/4],
|
||||
msgring_wakeup_sleep[i], msgring_wakeup_nosleep[i],
|
||||
msgring_nmsgs[i]);
|
||||
buf += nb;
|
||||
fs -= nb;
|
||||
}
|
||||
error = SYSCTL_OUT(req, xprintb, buf - xprintb);
|
||||
error = sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ ieee80211_sysctl_parent(SYSCTL_HANDLER_ARGS)
|
||||
struct ieee80211com *ic = arg1;
|
||||
const char *name = ic->ic_ifp->if_xname;
|
||||
|
||||
return SYSCTL_OUT(req, name, strlen(name));
|
||||
return SYSCTL_OUT_STR(req, name);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -596,7 +596,7 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
|
||||
static int
|
||||
sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int linesize = 128;
|
||||
const int linesize = 128;
|
||||
struct sbuf sb;
|
||||
int i, error;
|
||||
struct hc_metrics *hc_entry;
|
||||
@@ -605,7 +605,7 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
|
||||
#endif
|
||||
|
||||
sbuf_new(&sb, NULL, linesize * (V_tcp_hostcache.cache_count + 1),
|
||||
SBUF_FIXEDLEN);
|
||||
SBUF_INCLUDENUL);
|
||||
|
||||
sbuf_printf(&sb,
|
||||
"\nIP address MTU SSTRESH RTT RTTVAR BANDWIDTH "
|
||||
@@ -642,8 +642,9 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
|
||||
THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
|
||||
}
|
||||
#undef msec
|
||||
sbuf_finish(&sb);
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
|
||||
error = sbuf_finish(&sb);
|
||||
if (error == 0)
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
|
||||
sbuf_delete(&sb);
|
||||
return(error);
|
||||
}
|
||||
|
||||
@@ -186,6 +186,7 @@ struct sysctl_oid {
|
||||
|
||||
#define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)
|
||||
#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l)
|
||||
#define SYSCTL_OUT_STR(r, p) (r->oldfunc)(r, p, strlen(p) + 1)
|
||||
|
||||
int sysctl_handle_int(SYSCTL_HANDLER_ARGS);
|
||||
int sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS);
|
||||
|
||||
@@ -330,7 +330,7 @@ xenbusb_device_sysctl_handler(SYSCTL_HANDLER_ARGS)
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
return (SYSCTL_OUT(req, value, strlen(value)));
|
||||
return (SYSCTL_OUT_STR(req, value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+78
-53
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define BLOCKIF_SIG 0xb109b109
|
||||
|
||||
#define BLOCKIF_MAXREQ 33
|
||||
#define BLOCKIF_NUMTHR 8
|
||||
|
||||
enum blockop {
|
||||
BOP_READ,
|
||||
@@ -65,6 +66,7 @@ enum blockop {
|
||||
|
||||
enum blockstat {
|
||||
BST_FREE,
|
||||
BST_BLOCK,
|
||||
BST_PEND,
|
||||
BST_BUSY,
|
||||
BST_DONE
|
||||
@@ -76,6 +78,7 @@ struct blockif_elem {
|
||||
enum blockop be_op;
|
||||
enum blockstat be_status;
|
||||
pthread_t be_tid;
|
||||
off_t be_block;
|
||||
};
|
||||
|
||||
struct blockif_ctxt {
|
||||
@@ -88,16 +91,15 @@ struct blockif_ctxt {
|
||||
int bc_sectsz;
|
||||
int bc_psectsz;
|
||||
int bc_psectoff;
|
||||
pthread_t bc_btid;
|
||||
int bc_closing;
|
||||
pthread_t bc_btid[BLOCKIF_NUMTHR];
|
||||
pthread_mutex_t bc_mtx;
|
||||
pthread_cond_t bc_cond;
|
||||
int bc_closing;
|
||||
|
||||
/* Request elements and free/pending/busy queues */
|
||||
TAILQ_HEAD(, blockif_elem) bc_freeq;
|
||||
TAILQ_HEAD(, blockif_elem) bc_pendq;
|
||||
TAILQ_HEAD(, blockif_elem) bc_busyq;
|
||||
u_int bc_req_count;
|
||||
struct blockif_elem bc_reqs[BLOCKIF_MAXREQ];
|
||||
};
|
||||
|
||||
@@ -116,58 +118,83 @@ static int
|
||||
blockif_enqueue(struct blockif_ctxt *bc, struct blockif_req *breq,
|
||||
enum blockop op)
|
||||
{
|
||||
struct blockif_elem *be;
|
||||
|
||||
assert(bc->bc_req_count < BLOCKIF_MAXREQ);
|
||||
struct blockif_elem *be, *tbe;
|
||||
off_t off;
|
||||
int i;
|
||||
|
||||
be = TAILQ_FIRST(&bc->bc_freeq);
|
||||
assert(be != NULL);
|
||||
assert(be->be_status == BST_FREE);
|
||||
|
||||
TAILQ_REMOVE(&bc->bc_freeq, be, be_link);
|
||||
be->be_status = BST_PEND;
|
||||
be->be_req = breq;
|
||||
be->be_op = op;
|
||||
switch (op) {
|
||||
case BOP_READ:
|
||||
case BOP_WRITE:
|
||||
case BOP_DELETE:
|
||||
off = breq->br_offset;
|
||||
for (i = 0; i < breq->br_iovcnt; i++)
|
||||
off += breq->br_iov[i].iov_len;
|
||||
break;
|
||||
default:
|
||||
off = OFF_MAX;
|
||||
}
|
||||
be->be_block = off;
|
||||
TAILQ_FOREACH(tbe, &bc->bc_pendq, be_link) {
|
||||
if (tbe->be_block == breq->br_offset)
|
||||
break;
|
||||
}
|
||||
if (tbe == NULL) {
|
||||
TAILQ_FOREACH(tbe, &bc->bc_busyq, be_link) {
|
||||
if (tbe->be_block == breq->br_offset)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tbe == NULL)
|
||||
be->be_status = BST_PEND;
|
||||
else
|
||||
be->be_status = BST_BLOCK;
|
||||
TAILQ_INSERT_TAIL(&bc->bc_pendq, be, be_link);
|
||||
|
||||
bc->bc_req_count++;
|
||||
|
||||
return (0);
|
||||
return (be->be_status == BST_PEND);
|
||||
}
|
||||
|
||||
static int
|
||||
blockif_dequeue(struct blockif_ctxt *bc, struct blockif_elem **bep)
|
||||
blockif_dequeue(struct blockif_ctxt *bc, pthread_t t, struct blockif_elem **bep)
|
||||
{
|
||||
struct blockif_elem *be;
|
||||
|
||||
if (bc->bc_req_count == 0)
|
||||
return (ENOENT);
|
||||
|
||||
be = TAILQ_FIRST(&bc->bc_pendq);
|
||||
assert(be != NULL);
|
||||
assert(be->be_status == BST_PEND);
|
||||
TAILQ_FOREACH(be, &bc->bc_pendq, be_link) {
|
||||
if (be->be_status == BST_PEND)
|
||||
break;
|
||||
assert(be->be_status == BST_BLOCK);
|
||||
}
|
||||
if (be == NULL)
|
||||
return (0);
|
||||
TAILQ_REMOVE(&bc->bc_pendq, be, be_link);
|
||||
be->be_status = BST_BUSY;
|
||||
be->be_tid = bc->bc_btid;
|
||||
be->be_tid = t;
|
||||
TAILQ_INSERT_TAIL(&bc->bc_busyq, be, be_link);
|
||||
|
||||
*bep = be;
|
||||
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
blockif_complete(struct blockif_ctxt *bc, struct blockif_elem *be)
|
||||
{
|
||||
assert(be->be_status == BST_DONE);
|
||||
struct blockif_elem *tbe;
|
||||
|
||||
TAILQ_REMOVE(&bc->bc_busyq, be, be_link);
|
||||
if (be->be_status == BST_DONE || be->be_status == BST_BUSY)
|
||||
TAILQ_REMOVE(&bc->bc_busyq, be, be_link);
|
||||
else
|
||||
TAILQ_REMOVE(&bc->bc_pendq, be, be_link);
|
||||
TAILQ_FOREACH(tbe, &bc->bc_pendq, be_link) {
|
||||
if (tbe->be_req->br_offset == be->be_block)
|
||||
tbe->be_status = BST_PEND;
|
||||
}
|
||||
be->be_tid = 0;
|
||||
be->be_status = BST_FREE;
|
||||
be->be_req = NULL;
|
||||
TAILQ_INSERT_TAIL(&bc->bc_freeq, be, be_link);
|
||||
|
||||
bc->bc_req_count--;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -203,6 +230,8 @@ blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be)
|
||||
case BOP_DELETE:
|
||||
if (!bc->bc_candelete)
|
||||
err = EOPNOTSUPP;
|
||||
else if (bc->bc_rdonly)
|
||||
err = EROFS;
|
||||
else if (bc->bc_ischr) {
|
||||
arg[0] = br->br_offset;
|
||||
arg[1] = br->br_iov[0].iov_len;
|
||||
@@ -226,28 +255,27 @@ blockif_thr(void *arg)
|
||||
{
|
||||
struct blockif_ctxt *bc;
|
||||
struct blockif_elem *be;
|
||||
pthread_t t;
|
||||
|
||||
bc = arg;
|
||||
t = pthread_self();
|
||||
|
||||
pthread_mutex_lock(&bc->bc_mtx);
|
||||
for (;;) {
|
||||
pthread_mutex_lock(&bc->bc_mtx);
|
||||
while (!blockif_dequeue(bc, &be)) {
|
||||
while (blockif_dequeue(bc, t, &be)) {
|
||||
pthread_mutex_unlock(&bc->bc_mtx);
|
||||
blockif_proc(bc, be);
|
||||
pthread_mutex_lock(&bc->bc_mtx);
|
||||
blockif_complete(bc, be);
|
||||
}
|
||||
pthread_cond_wait(&bc->bc_cond, &bc->bc_mtx);
|
||||
pthread_mutex_unlock(&bc->bc_mtx);
|
||||
|
||||
/*
|
||||
* Check ctxt status here to see if exit requested
|
||||
*/
|
||||
/* Check ctxt status here to see if exit requested */
|
||||
if (bc->bc_closing)
|
||||
pthread_exit(NULL);
|
||||
break;
|
||||
pthread_cond_wait(&bc->bc_cond, &bc->bc_mtx);
|
||||
}
|
||||
pthread_mutex_unlock(&bc->bc_mtx);
|
||||
|
||||
/* Not reached */
|
||||
pthread_exit(NULL);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -386,16 +414,16 @@ blockif_open(const char *optstr, const char *ident)
|
||||
TAILQ_INIT(&bc->bc_freeq);
|
||||
TAILQ_INIT(&bc->bc_pendq);
|
||||
TAILQ_INIT(&bc->bc_busyq);
|
||||
bc->bc_req_count = 0;
|
||||
for (i = 0; i < BLOCKIF_MAXREQ; i++) {
|
||||
bc->bc_reqs[i].be_status = BST_FREE;
|
||||
TAILQ_INSERT_HEAD(&bc->bc_freeq, &bc->bc_reqs[i], be_link);
|
||||
}
|
||||
|
||||
pthread_create(&bc->bc_btid, NULL, blockif_thr, bc);
|
||||
|
||||
snprintf(tname, sizeof(tname), "blk-%s", ident);
|
||||
pthread_set_name_np(bc->bc_btid, tname);
|
||||
for (i = 0; i < BLOCKIF_NUMTHR; i++) {
|
||||
pthread_create(&bc->bc_btid[i], NULL, blockif_thr, bc);
|
||||
snprintf(tname, sizeof(tname), "blk-%s-%d", ident, i);
|
||||
pthread_set_name_np(bc->bc_btid[i], tname);
|
||||
}
|
||||
|
||||
return (bc);
|
||||
}
|
||||
@@ -409,13 +437,13 @@ blockif_request(struct blockif_ctxt *bc, struct blockif_req *breq,
|
||||
err = 0;
|
||||
|
||||
pthread_mutex_lock(&bc->bc_mtx);
|
||||
if (bc->bc_req_count < BLOCKIF_MAXREQ) {
|
||||
if (!TAILQ_EMPTY(&bc->bc_freeq)) {
|
||||
/*
|
||||
* Enqueue and inform the block i/o thread
|
||||
* that there is work available
|
||||
*/
|
||||
blockif_enqueue(bc, breq, op);
|
||||
pthread_cond_signal(&bc->bc_cond);
|
||||
if (blockif_enqueue(bc, breq, op))
|
||||
pthread_cond_signal(&bc->bc_cond);
|
||||
} else {
|
||||
/*
|
||||
* Callers are not allowed to enqueue more than
|
||||
@@ -481,11 +509,7 @@ blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq)
|
||||
/*
|
||||
* Found it.
|
||||
*/
|
||||
TAILQ_REMOVE(&bc->bc_pendq, be, be_link);
|
||||
be->be_status = BST_FREE;
|
||||
be->be_req = NULL;
|
||||
TAILQ_INSERT_TAIL(&bc->bc_freeq, be, be_link);
|
||||
bc->bc_req_count--;
|
||||
blockif_complete(bc, be);
|
||||
pthread_mutex_unlock(&bc->bc_mtx);
|
||||
|
||||
return (0);
|
||||
@@ -546,7 +570,7 @@ int
|
||||
blockif_close(struct blockif_ctxt *bc)
|
||||
{
|
||||
void *jval;
|
||||
int err;
|
||||
int err, i;
|
||||
|
||||
err = 0;
|
||||
|
||||
@@ -556,8 +580,9 @@ blockif_close(struct blockif_ctxt *bc)
|
||||
* Stop the block i/o thread
|
||||
*/
|
||||
bc->bc_closing = 1;
|
||||
pthread_cond_signal(&bc->bc_cond);
|
||||
pthread_join(bc->bc_btid, &jval);
|
||||
pthread_cond_broadcast(&bc->bc_cond);
|
||||
for (i = 0; i < BLOCKIF_NUMTHR; i++)
|
||||
pthread_join(bc->bc_btid[i], &jval);
|
||||
|
||||
/* XXX Cancel queued i/o's ??? */
|
||||
|
||||
|
||||
@@ -840,10 +840,11 @@ handle_identify(struct ahci_port *p, int slot, uint8_t *cfis)
|
||||
} else {
|
||||
uint16_t buf[256];
|
||||
uint64_t sectors;
|
||||
int sectsz, psectsz, psectoff, candelete;
|
||||
int sectsz, psectsz, psectoff, candelete, ro;
|
||||
uint16_t cyl;
|
||||
uint8_t sech, heads;
|
||||
|
||||
ro = blockif_is_ro(p->bctx);
|
||||
candelete = blockif_candelete(p->bctx);
|
||||
sectsz = blockif_sectsz(p->bctx);
|
||||
sectors = blockif_size(p->bctx) / sectsz;
|
||||
@@ -906,7 +907,7 @@ handle_identify(struct ahci_port *p, int slot, uint8_t *cfis)
|
||||
buf[101] = (sectors >> 16);
|
||||
buf[102] = (sectors >> 32);
|
||||
buf[103] = (sectors >> 48);
|
||||
if (candelete) {
|
||||
if (candelete && !ro) {
|
||||
buf[69] |= ATA_SUPPORT_RZAT | ATA_SUPPORT_DRAT;
|
||||
buf[105] = 1;
|
||||
buf[169] = ATA_SUPPORT_DSM_TRIM;
|
||||
|
||||
@@ -170,9 +170,9 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq)
|
||||
int writeop, type;
|
||||
off_t offset;
|
||||
struct iovec iov[VTBLK_MAXSEGS + 2];
|
||||
uint16_t flags[VTBLK_MAXSEGS + 2];
|
||||
uint16_t idx, flags[VTBLK_MAXSEGS + 2];
|
||||
|
||||
n = vq_getchain(vq, iov, VTBLK_MAXSEGS + 2, flags);
|
||||
n = vq_getchain(vq, &idx, iov, VTBLK_MAXSEGS + 2, flags);
|
||||
|
||||
/*
|
||||
* The first descriptor will be the read-only fixed header,
|
||||
@@ -258,7 +258,7 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq)
|
||||
* Return the descriptor back to the host.
|
||||
* We wrote 1 byte (our status) to host.
|
||||
*/
|
||||
vq_relchain(vq, 1);
|
||||
vq_relchain(vq, idx, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -266,7 +266,6 @@ pci_vtblk_notify(void *vsc, struct vqueue_info *vq)
|
||||
{
|
||||
struct pci_vtblk_softc *sc = vsc;
|
||||
|
||||
vq_startchains(vq);
|
||||
while (vq_has_descs(vq))
|
||||
pci_vtblk_proc(sc, vq);
|
||||
vq_endchains(vq, 1); /* Generate interrupt if appropriate. */
|
||||
|
||||
@@ -288,6 +288,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
|
||||
struct vqueue_info *vq;
|
||||
void *vrx;
|
||||
int len, n;
|
||||
uint16_t idx;
|
||||
|
||||
/*
|
||||
* Should never be called without a valid tap fd
|
||||
@@ -310,7 +311,6 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
|
||||
* Check for available rx buffers
|
||||
*/
|
||||
vq = &sc->vsc_queues[VTNET_RXQ];
|
||||
vq_startchains(vq);
|
||||
if (!vq_has_descs(vq)) {
|
||||
/*
|
||||
* Drop the packet and try later. Interrupt on
|
||||
@@ -325,7 +325,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
|
||||
/*
|
||||
* Get descriptor chain.
|
||||
*/
|
||||
n = vq_getchain(vq, iov, VTNET_MAXSEGS, NULL);
|
||||
n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL);
|
||||
assert(n >= 1 && n <= VTNET_MAXSEGS);
|
||||
|
||||
/*
|
||||
@@ -362,7 +362,7 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
|
||||
/*
|
||||
* Release this chain and handle more chains.
|
||||
*/
|
||||
vq_relchain(vq, len + sc->rx_vhdrlen);
|
||||
vq_relchain(vq, idx, len + sc->rx_vhdrlen);
|
||||
} while (vq_has_descs(vq));
|
||||
|
||||
/* Interrupt if needed, including for NOTIFY_ON_EMPTY. */
|
||||
@@ -401,13 +401,14 @@ pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vqueue_info *vq)
|
||||
struct iovec iov[VTNET_MAXSEGS + 1];
|
||||
int i, n;
|
||||
int plen, tlen;
|
||||
uint16_t idx;
|
||||
|
||||
/*
|
||||
* Obtain chain of descriptors. The first one is
|
||||
* really the header descriptor, so we need to sum
|
||||
* up two lengths: packet length and transfer length.
|
||||
*/
|
||||
n = vq_getchain(vq, iov, VTNET_MAXSEGS, NULL);
|
||||
n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL);
|
||||
assert(n >= 1 && n <= VTNET_MAXSEGS);
|
||||
plen = 0;
|
||||
tlen = iov[0].iov_len;
|
||||
@@ -420,7 +421,7 @@ pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vqueue_info *vq)
|
||||
pci_vtnet_tap_tx(sc, &iov[1], n - 1, plen);
|
||||
|
||||
/* chain is processed, release it and set tlen */
|
||||
vq_relchain(vq, tlen);
|
||||
vq_relchain(vq, idx, tlen);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -479,7 +480,6 @@ pci_vtnet_tx_thread(void *param)
|
||||
sc->tx_in_progress = 1;
|
||||
pthread_mutex_unlock(&sc->tx_mtx);
|
||||
|
||||
vq_startchains(vq);
|
||||
do {
|
||||
/*
|
||||
* Run through entries, placing them into
|
||||
|
||||
@@ -103,18 +103,17 @@ pci_vtrnd_notify(void *vsc, struct vqueue_info *vq)
|
||||
struct iovec iov;
|
||||
struct pci_vtrnd_softc *sc;
|
||||
int len;
|
||||
uint16_t idx;
|
||||
|
||||
sc = vsc;
|
||||
|
||||
vq_startchains(vq);
|
||||
|
||||
if (sc->vrsc_fd < 0) {
|
||||
vq_endchains(vq, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
while (vq_has_descs(vq)) {
|
||||
vq_getchain(vq, &iov, 1, NULL);
|
||||
vq_getchain(vq, &idx, &iov, 1, NULL);
|
||||
|
||||
len = read(sc->vrsc_fd, iov.iov_base, iov.iov_len);
|
||||
|
||||
@@ -126,7 +125,7 @@ pci_vtrnd_notify(void *vsc, struct vqueue_info *vq)
|
||||
/*
|
||||
* Release this chain and handle more
|
||||
*/
|
||||
vq_relchain(vq, len);
|
||||
vq_relchain(vq, idx, len);
|
||||
}
|
||||
vq_endchains(vq, 1); /* Generate interrupt if appropriate. */
|
||||
}
|
||||
|
||||
+10
-9
@@ -97,6 +97,7 @@ vi_reset_dev(struct virtio_softc *vs)
|
||||
for (vq = vs->vs_queues, i = 0; i < nvq; vq++, i++) {
|
||||
vq->vq_flags = 0;
|
||||
vq->vq_last_avail = 0;
|
||||
vq->vq_save_used = 0;
|
||||
vq->vq_pfn = 0;
|
||||
vq->vq_msix_idx = VIRTIO_MSI_NO_VECTOR;
|
||||
}
|
||||
@@ -188,6 +189,7 @@ vi_vq_init(struct virtio_softc *vs, uint32_t pfn)
|
||||
/* Mark queue as allocated, and start at 0 when we use it. */
|
||||
vq->vq_flags = VQ_ALLOC;
|
||||
vq->vq_last_avail = 0;
|
||||
vq->vq_save_used = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -247,12 +249,12 @@ _vq_record(int i, volatile struct virtio_desc *vd, struct vmctx *ctx,
|
||||
* that vq_has_descs() does one).
|
||||
*/
|
||||
int
|
||||
vq_getchain(struct vqueue_info *vq,
|
||||
vq_getchain(struct vqueue_info *vq, uint16_t *pidx,
|
||||
struct iovec *iov, int n_iov, uint16_t *flags)
|
||||
{
|
||||
int i;
|
||||
u_int ndesc, n_indir;
|
||||
u_int idx, head, next;
|
||||
u_int idx, next;
|
||||
volatile struct virtio_desc *vdir, *vindir, *vp;
|
||||
struct vmctx *ctx;
|
||||
struct virtio_softc *vs;
|
||||
@@ -295,8 +297,8 @@ vq_getchain(struct vqueue_info *vq,
|
||||
* index, but we just abort if the count gets excessive.
|
||||
*/
|
||||
ctx = vs->vs_pi->pi_vmctx;
|
||||
head = vq->vq_avail->va_ring[idx & (vq->vq_qsize - 1)];
|
||||
next = head;
|
||||
*pidx = next = vq->vq_avail->va_ring[idx & (vq->vq_qsize - 1)];
|
||||
vq->vq_last_avail++;
|
||||
for (i = 0; i < VQ_MAX_DESCRIPTORS; next = vdir->vd_next) {
|
||||
if (next >= vq->vq_qsize) {
|
||||
fprintf(stderr,
|
||||
@@ -377,9 +379,9 @@ vq_getchain(struct vqueue_info *vq,
|
||||
* and used its positive return value.)
|
||||
*/
|
||||
void
|
||||
vq_relchain(struct vqueue_info *vq, uint32_t iolen)
|
||||
vq_relchain(struct vqueue_info *vq, uint16_t idx, uint32_t iolen)
|
||||
{
|
||||
uint16_t head, uidx, mask;
|
||||
uint16_t uidx, mask;
|
||||
volatile struct vring_used *vuh;
|
||||
volatile struct virtio_used *vue;
|
||||
|
||||
@@ -395,11 +397,10 @@ vq_relchain(struct vqueue_info *vq, uint32_t iolen)
|
||||
*/
|
||||
mask = vq->vq_qsize - 1;
|
||||
vuh = vq->vq_used;
|
||||
head = vq->vq_avail->va_ring[vq->vq_last_avail++ & mask];
|
||||
|
||||
uidx = vuh->vu_idx;
|
||||
vue = &vuh->vu_ring[uidx++ & mask];
|
||||
vue->vu_idx = head; /* ie, vue->id = head */
|
||||
vue->vu_idx = idx;
|
||||
vue->vu_tlen = iolen;
|
||||
vuh->vu_idx = uidx;
|
||||
}
|
||||
@@ -436,8 +437,8 @@ vq_endchains(struct vqueue_info *vq, int used_all_avail)
|
||||
* entire avail was processed, we need to interrupt always.
|
||||
*/
|
||||
vs = vq->vq_vs;
|
||||
new_idx = vq->vq_used->vu_idx;
|
||||
old_idx = vq->vq_save_used;
|
||||
vq->vq_save_used = new_idx = vq->vq_used->vu_idx;
|
||||
if (used_all_avail &&
|
||||
(vs->vs_negotiated_caps & VIRTIO_F_NOTIFY_ON_EMPTY))
|
||||
intr = 1;
|
||||
|
||||
+2
-16
@@ -424,20 +424,6 @@ vq_has_descs(struct vqueue_info *vq)
|
||||
vq->vq_avail->va_idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by virtio driver as it starts processing chains. Each
|
||||
* completed chain (obtained from vq_getchain()) is released by
|
||||
* calling vq_relchain(), then when all are done, vq_endchains()
|
||||
* can tell if / how-many chains were processed and know whether
|
||||
* and how to generate an interrupt.
|
||||
*/
|
||||
static inline void
|
||||
vq_startchains(struct vqueue_info *vq)
|
||||
{
|
||||
|
||||
vq->vq_save_used = vq->vq_used->vu_idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deliver an interrupt to guest on the given virtual queue
|
||||
* (if possible, or a generic MSI interrupt if not using MSI-X).
|
||||
@@ -465,9 +451,9 @@ int vi_intr_init(struct virtio_softc *vs, int barnum, int use_msix);
|
||||
void vi_reset_dev(struct virtio_softc *);
|
||||
void vi_set_io_bar(struct virtio_softc *, int);
|
||||
|
||||
int vq_getchain(struct vqueue_info *vq,
|
||||
int vq_getchain(struct vqueue_info *vq, uint16_t *pidx,
|
||||
struct iovec *iov, int n_iov, uint16_t *flags);
|
||||
void vq_relchain(struct vqueue_info *vq, uint32_t iolen);
|
||||
void vq_relchain(struct vqueue_info *vq, uint16_t idx, uint32_t iolen);
|
||||
void vq_endchains(struct vqueue_info *vq, int used_all_avail);
|
||||
|
||||
uint64_t vi_pci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
|
||||
|
||||
Reference in New Issue
Block a user