Thursday, September 11, 2008

man-pages goes git (at last!)

[Update: 19 Sep 2008: when I first attempted the git import, I didn't import the subversion tags into git. I've updated and expanded this post to include the required details to do that.]

When I inherited man-pages, there was no version control system (VCS) in use. To help myself keep track of changes, I've been running a private subversion repository since I took over as maintainer (i.e., since man-pages-2.00), but I never got round to hosting it on a public server so that people could pull from it (requests for such a facility were only occasional). Instead, people wanting to send patches would just grab the latest tarball from the downloads directory, patch the required source file, and email me the patch.

Somewhat more frequent requests for a public repository, and the fact that the Linux world is nowadays mostly oriented around the git distributed version control system, have gradually created a pressure to change things. So, I'm taking baby steps towards using git for man-pages. Here goes...

Importing from subversion to git

I found the Simplistic Complexity blog's simple instructions on subversion-to-git migration quite useful (though it didn't supply all of the details I needed for importing subversion tags).

My subversion repository had a somewhat non-standard layout, which affected the options (see the git svn init command below) that I needed to do an import that included my subversion tags. (Thanks to various people on the git mailing list who helped me find the right way to do things, especially Björn Steinbrink and Michael Gruber.) The following subversion commands give an idea of the layout:

$ svn list file:///home/mtk/man-pages-rep
branches/
tags/
trunk/
$ svn list file:///home/mtk/man-pages-rep/trunk
man-pages/
$ svn list file:///home/mtk/man-pages-rep/trunk/man-pages
Changes
Changes.old
Makefile
README
...
man7/
man8/
scripts/
$ svn list file:///home/mtk/man-pages-rep/tags
man-pages-2.00/
man-pages-2.01/
...
man-pages-3.08/
man-pages-3.09/
$ svn list file:///home/mtk/man-pages-rep/tags
man-pages-2.00
man-pages-2.01
...
man-pages-3.08
man-pages-3.09
$ svn list file:///home/mtk/man-pages-rep/tags/man-pages-2.00
man-pages
$ svn list file:///home/mtk/man-pages-rep/tags/man-pages-2.01
man-pages
[and so on]
$ svn list file:///home/mtk/man-pages-rep/branches
$
[i.e., no branches, since this has been a linear svn repo.]
Set up an empty, temporary git repository, in the process informing git about the location of the subversion repository from which the import should be done:
$ cd $HOME
$ mkdir man-pages-git-tmp
$ cd man-pages-git-tmp
$ git svn init file:///home/mtk/man-pages-rep/ \
-T trunk/man-pages \
-b branches/*/man-pages
-t tags/*/man-pages
--no-metadata
Initialized empty Git repository in .git/
Tell git about the names of users in the subversion commit logs. Because the subversion repository was private (I just took other people's emailed input and made changes as required), I'm the only user. That means that the historical information in the repository will be bogus, suggesting that I'm responsible for all of the nearly 5000 commits to the repository, when it's probably more like 75%. My apologies to everyone else. Something like the true story for man-pages 2.00 through to 3.09 can be found here.
$ cat > ~/users.txt
mtk = Michael Kerrisk
^D
$ git config svn.authorsfile ~/users.txt
Do the import:
$ time git svn fetch
[...]
M Changes
r4917 = 93a6e8f9ee5d0710a084425548775348389e2900 (git-svn)
Checking out files: 100% (1925/1925), done.
Checked out HEAD:
file:///home/mtk/man-pages-rep/trunk/man-pages r4917

real 70m24.850s
user 14m46.571s
sys 22m29.852s
And yes, I definitely need some faster hardware...

At this point, git branch -a showed that I had imported the subversion tags into git. But the tags still need to be turned into proper git tags. This requires a command for each tag, which can be automated in a script. (Thanks to Heikki Orsila who pointed out to me that this step was required, and who supplied the script.)
$ cat git-svn-tags.sh
#!/bin/sh
#
git branch -a | grep tags/ | while read tag ; do
tagname=$(echo $tag | cut -d/ -f2)
commit=$(git rev-parse $tag)
res=$(git log master | grep "^commit $commit")
if test -z "$res" ; then
# take the parent commit for the tag commit (found in master)
commit=$(git rev-parse $tag^)
fi
echo $tagname $commit
git tag -a $tagname $commit -m "This is $tagname"
done

$ sh ~/git-svn-tags.sh
man-pages-2.00 105a35bc69bd3088d69f5d3c94d22e6595e223d2
man-pages-2.01 972a9aee950d4df97cc1f81147b64fe52007dfc7
...
man-pages-3.08 5c8cbdc1b2c9b5a1ebb8626361ea01cb73965636
man-pages-3.09 81468e1308f643ffd5718809379c074ff75dc311
$ git tag -l
man-pages-2.00
man-pages-2.01
...
man-pages-3.08
man-pages-3.09
Clone the temporary repository, to produce a clean repository from which any lingering cruft that was used to support git svn has been removed:
$ git clone man-pages-git-tmp man-pages-git
Initialized empty Git repository in /home/mtk/man-pages-git/.git/
0 blocks
And then run a garbage collection to clean up any remaining unneeded files, and otherwise improve the efficiency of the repository:
$ git gc
Counting objects: 36341, done.
Compressing objects: 100% (12059/12059), done.
Writing objects: 100% (36341/36341), done.
Total 36341 (delta 29117), reused 29623 (delta 23595)
Hosting the git repository on kernel.org

The public git repository is to be hosted on kernel.org. Quite a while back the admins there already set up a location for a man-pages git repository. Jeremy Kerr kindly held my hand through the hurdles of the initial set up.

On kernel.org, the admins assigned man-pages a repository location of /pub/scm/docs/man-pages. So, let's create an empty repository there:
$ ssh mtk@master.kernel.org
mtk@master.kernel.org's password:
[mtk@hera man-pages]$ cd /pub/scm/docs/man-pages
[mtk@hera man-pages]$ git init
[mtk@hera man-pages]$ mv .git/ man-pages.git
[mtk@hera man-pages]$ exit
Back on my local machine, modify the git repository's config file so that I can write simple git push commands to push changes onto the kernel.org repository
$ cat >> ~/man-pages-git/.git/config
[remote "kernel.org"]
url = ssh://master.kernel.org/pub/scm/docs/man-pages/man-pages.git
push = +refs/heads/master:refs/heads/master
And then do the push to kernel.org:
$ cd $HOME/man-pages-git
$ git push kernel.org
mtk@master.kernel.org's password:
Counting objects: 36341, done.
Compressing objects: 100% (12059/12059), done.
Writing objects: 100% (36341/36341), 8.62 MiB 681 KiB/s, done.
Total 36341 (delta 29117), reused 29623 (delta 23595)
To ssh://master.kernel.org/pub/scm/docs/man-pages/man-pages.git
* [new branch] master -> master
Log into kernel.org and give the repository a public description:
$ ssh mtk@master.kernel.org
mtk@master.kernel.org's password:
[mtk@hera man-pages]$ cat > /pub/scm/docs/man-pages/man-pages.git/description
Man pages for Linux kernel and glibc APIs
^D
[mtk@hera man-pages]$ exit
And then we have the repository visible and ready for use at http://git.kernel.org/, and you can clone it using the following command:
$ git clone git://git.kernel.org/pub/scm/docs/man-pages/man-pages.git
PS In case it's not clear: only use git to submit changes to man-pages if that's your preference. It's still possible to submit patches the good old-fashioned way, by grabbing the latest release (tarballs will continue to be released as usual every week or two), editing the required source file(s), and sending me a diff -u patch by email.

Wednesday, September 10, 2008

man-pages-3.09 is released

I've uploaded man-pages-3.09 into the release directory (or view the online pages). Notable changes in man-pages-3.09 are:

  • A new fopencookie(3) page, documents a library function that allows a custom implementation of a stdio stream.
  • A new networks(5) page (adopted from Debian) documents the /etc/networks file.
  • Feature test macro requirements were added or fixed for various pages.
  • Many parts of the hsearch(3) man page were fixed and rewritten.
Dan Jacobson remarked that people who read the COLOPHON at the end of each man page may have a kernel or glibc bug to report, rather than a man-pages bug report, but that following the URL in the COLOPHON only leads to a page describing how to report documentation bugs. So, I wrote a new page giving some pointers about reporting kernel and glibc bugs, and that page is linked from the man-pages reporting bugs page.

Fast fertig auf da Wiesn


Wednesday, August 27, 2008

man-pages-3.08 is released

I've uploaded man-pages-3.08 into the release directory (or view the online pages). Notable changes in man-pages-3.08 are:

  • A new numa(7) page gives an overview of the Linux NUMA interfaces.
  • A new getnetent_r(3) page documents getnetent_r(), getnetbyname_r(), and getnetbyaddr_r(), the reentrant equivalents of getnetent(), getnetbyname(), and getnetbyaddr().
  • A new getprotoent_r(3) page documents getprotoent_r(), getprotobyname_r(), and getprotobynumber_r(), the reentrant equivalents of getprotoent(), getprotobyname(), and getprotobynumber().
  • A new getrpcent_r(3) page documents getrpcent_r(), getrpcbyname_r(), and
    getrpcbynumber_r(), the reentrant equivalents of getrpcent(), getrpcbyname(), and getrpcbynumber().
  • A new getservent_r(3) page documents documents getservent_r(), getservbyname_r(), and getservbyport_r(), the reentrant equivalents of getservent(), getservbyname(), and getservbyport().
  • Further updates related to changes in the recently approved POSIX.1-2008 standard.

Friday, August 15, 2008

Speaking at LPC

My paper for Linux Plumbers Conference (16-19 September, Portland, OR) got accepted :-). I'll be considering the question: Who owns the interface?

Tuesday, August 12, 2008

man-pages-3.07 is released

I've uploaded man-pages-3.07 into the release directory (or view the online pages). Notable changes in man-pages-3.07 are:

  • A new move_pages(2) page, written by Christoph Lameter, documents the move_pages() system call. This page was formerly part of the numactl package, but has been revised and moved into man-pages (its natural home, since it is a kernel interface).
  • A new clock_getcpuclockid(3) page describes the clock_getcpuclockid() library function.
  • A new udplite(7) page, written by Gerrit Renker, documents the Linux implementation (since kernel 2.6.20) of the UDP-Lite transport layer protocol.
  • The proc(5) man page adds a description of the /proc/PID/numa_maps file.
  • Various updates and improvements by Lee Schermerhorn for the mbind(2), get_mempolicy(2), and set_mempolicy(2) pages.
  • Following on from last week's big update to the math man pages, there are a few more changes to these pages. Most notably, where error-reporting details have differed (from glibc 2.8) in earlier versions of glibc, the differences have been noted in the man pages. Currently, the details have been extended back until glibc 2.3.2, but I hope to extend them back further, when I can get test results. If you want to help, look here.
  • On 24 July, the Governing Board of The Open Group approved the 2008 revisions of POSIX.1. Among other things, POSIX.1-2008 marks some previously specified functions as obsolete, and drops the specifications of some other functions altogether. The manual pages have been updated to reflect all of these changes. (The standard should be published in final form after approval by the IEEE, but in the meantime you can get access to the draft by joining the Austin group.)
  • VERSIONS sections have been added to the man pages of many library functions to indicate the glibc version where the function first appeared.

Grünegg Fenster

Friday, August 8, 2008

Translating man-pages

Update, 2020-06-20: I've maintained the post below mainly for historical interest. However things have moved along quite a bit in 12 years, rendering various of my suggestions obsolete. If you are thinking about translating manual pages, see the manpages-I10n project, which oversees translations into several languages and employs a range of useful tooling for translation.

Lately, I've gotten a few requests for information about how to translate man-pages into other languages. First off, I should say that I have never translated man-pages. But I have communicated with a few people who do. So these are my current thoughts... Do you really want to do this? Before you answer this, consider the following:
  • man-pages contains the documentation of the Linux and glibc programming APIs (i.e., pages in Sections 2, 3, 4, 5, and 7). Is this the set of man pages that your group of language speakers most need? If, for example, you are more interested in translating pages for end users, then you might want instead to translate pages in the coreutils package. (More generally, if you want to find out which package a particular man page belongs to, take a look here.)
  • How big is the target audience? Your target audience is primarily programmers. What proportion of them aren't able to read English well enough to read man pages, and therefore would benefit from a translation? Is that group big enough to warrant the effort of a translation? Or is there perhaps a better place where you can invest your time in working on Linux?
  • How much time do you have? There are currently around 850 pages in man-pages, amounting to perhaps 2000 pages of printed text. My guess is that this amounts to one to two person years of translation work. In other words, you'll need to have a team of translators, if you intend to complete the translation in any reasonable time.
  • What is your longer term commitment? man-pages is a moving target: starting a couple of months ago, I'm now working full time on man-pages, and I make a release every week or so. The French translator estimates that there is around two days' work for him translating each release. Now, I may not be working full time on man-pages forever, and therefore the required translation effort may decrease some day, but the point remains that there is a significant ongoing effort required to keep a translation up to date and useful.

The size of the translation effort should not be underestimated. It is because it is so large that to date there has been only one complete and up-to-date translation: the French translation. (For a while, there was a fairly full German translation, but it seems to have languished for a few years now.) The state of the French translation has largely been down to the extraordinary work of two people: Christophe Blaess, and more recently, Alain Portal. (In fact, there are nowadays two French translations which cooperate to some extent: the Debian distribution has a team doing a French translation of man-pages.) But nowadays even the French translator(s) have started to feel the strain resulting from the recent increase in my output.

If you decide you really want to do a translation (and think very carefully before you do decide that!), then I have a few thoughts on how you go about it.

Tools: I have no real recommendations here (since I never translated man-pages). But it's worth mentioning that the Debian French translators use po4a, and see it as very beneficial for their work, especially for facilitating the work of a team of translators.

Other than that, I'd say that you need to:

  • Estimate the time required to translate the 850 pages in man-pages, and decide if you have the necessary number translators who have sufficient time to complete the work.
  • Divide the work up so that your translators can work independently on translations. I suggest you divide the pages up into small, related parcels. For example, the POSIX message queue pages (mq_*) could be a parcel translated by a single translator, or the math man pages could be a parcel translated by a single translator, etc.
  • Come up with a review plan, so that each translation by one member of your team is reviewed by at least one other member.
  • Devise a glossary of terminology, so that you all translate English technical terms ("e.g., shared memory segment") into the same terms in the target language.
  • Plan for ongoing maintenance, so that as the English man pages are updated, then the translated pages are also updated. Don't underestimate the amount of this work!

My suggestion is that if you go forward with a translation project, then:

  • Pick a particular man-pages release -- let's say man-pages-3.x -- and translate all of the pages in that version.
  • When that is completed, you can then update your translation with all of the changes that have occurred in the English original since release man-pages-3.x. I keep fairly detailed changelogs which should assist you during this phase of the work.

I suggest doing things this way since I estimate that trying to do a translation while simultaneously trying to keep up with changes in already translated pages would just prove too difficult. You might decide otherwise.

And finally... did I mention that you should think long and hard before embarking on a translation of man-pages?

[12 Aug 08: minor updates, to point out exactly which sections are in man-pages, and to suggest more appropriate pages to translate, if targeting end users.]

Wednesday, August 6, 2008

Help request: testing of math function error reporting

As I mentioned in my previous post, as of man-pages-3.06, the math man pages now describe the error-reporting behavior of the math functions as at glibc 2.8. I'd like to extend those descriptions to cover differences in older glibc versions. In order to do that, I've written some scripts to check the error-reporting behavior of the math functions, and I'd like to run them on as many different versions of glibc as possible.

If you'd like to help, and you have an x86 system with an older glibc (look at the version number in the first line of output produced by the command /lib/libc.so.6), run the script in this tarball (see the README file inside the tarball for details), and send me the resulting log file (email to mtk.manpages AT gmail.com).

Updated, 2012- 03-06: Fix link to tarball

Math functions and error reporting

Math functions are different from most other library functions in the kinds of errors that they report, and in the way that they report errors. Broadly speaking, a math function can fail for one of the following reasons:

  • Domain error: an argument to the function was outside the range for which the function was defined. For example, the call sqrt(-1.0) gives a domain error because a negative number does not have (real) square root. When a domain error occurs, a math function typicall returns a NaN (not-a-number).
  • Pole error: the function result is an exact infinity. For example log(0.0) is negative infinity. When a pole error occurs, most math functions return the floating-point representation of positive or negative infinity, as appropriate (i.e., HUGE_VAL or -HUGE_VAL for functions returning a double).
  • Range error (overflow): an overflow occurs if the function result is too large to be represented as a floating-point number. For example, exp(1e10) produces a number too large to represent in a double. When an overflow occurs, most math functions return the floating-point representation of positive or negative infinity, as appropriate (i.e., HUGE_VAL or -HUGE_VAL for functions returning a double).
  • Range error (underflow): an underflow occurs if the function result is so small that it can't be represented as a (normalized) floating-point number. For example, exp(-1e10) produces a number too large to represent in a double. When an underflow occurs, a math function usually either returns a (signed) zero, or a subnormal value, as appropriate.

(More details can be found in the math_error(7) man page.)

Many library functions report an error by returning a NULL pointer or an integer -1. Neither of these mechanisms would be suitable for math functions: these functions usually return a floating-point value, and -1 is in many cases a valid successful return. For this reasons, the C99 and POSIX.1-2001 standards define two other mechanisms by which math functions can report errors.

The first of the error-reporting mechanisms is to use the traditional errno variable. We set the errno to zero before the call, and if it has a non-zero value after the call, then an error occurred. On error, errno is set as follows:

  • Domain error: EDOM

  • Pole error: ERANGE

  • Overflow: ERANGE

  • Underflow: ERANGE
(These settings do of course make it hard to distinguish the last three types of errors.)

The other error-reporting mechanism is exceptions. For each of the errors described above, the system raises an exception, and the fetestexcept() library function can be used to check whether an exception occurred. In order to use this mechanism we do the following:

  1. Call feclearexcept(FE_ALL_EXCEPT) to clear any existing exceptions.

  2. Call the math library function.

  3. Call fetestexcept(FE_INVALID FE_DIVBYZERO FE_OVERFLOW FE_UNDERFLOW).

If the math function was successful, then fetestexcept() returns 0. If an error occurred while calling the math function, then fetestexcept() returns a bit mask indicating the error. In this bit mask, exactly one of FE_INVALID, FE_DIVBYZERO, FE_OVERFLOW, or FE_UNDERFLOW will be set. The exceptions raised for each error are:

  • Domain error: invalid exception (FE_INVALID)

  • Pole error: divide-by-zero exception (FE_DIVBYZERO)

  • Overflow: overflow exception (FE_OVERFLOW)

  • Underflow: underflow exception (FE_UNDERFLOW)

C99 and POSIX.1-2001 require an implementation to support at least one of the error-reporting mechanisms for all math functions, and allow both to be supported. The standards specify an identifier, math_errhandling, that an implementation should set to indicate which mechanisms are supported. If (math_errhandling & MATH_ERRNO) is non-zero, then errno is set to indicate errors. If (math_errhandling & MATH_EXCEPT) is non-zero ,then exceptions are raised on errors.

The CONFORMANCE file in the glibc sources has long explained that:

Implementing MATH_ERRNO, MATH_ERREXCEPT and math_errhandling in needs compiler support: see
http://sources.redhat.com/ml/libc-hacker/2000-06/msg00008.html
http://sources.redhat.com/ml/libc-hacker/2000-06/msg00014.html
http://sources.redhat.com/ml/libc-hacker/2000-06/msg00015.html

But to date this support has not arrived. In any case, this support is a somewhat moot point, since it transpires that neither of the mechanisms is supported by all of the math functions in glibc: most (but not all) support exceptions, many support both exceptions and errno, a few support errno but not exceptions, and one or two functions support neither mechanism. To make things even worse, the man pages didn't fully and correctly describe the details for each math function. Since man-pages-3.06, the details should now be accurate, at least for glibc 2.8.

Ideally, all of the glibc math functions would support both mechanisms, so that programs that depend on either mechanism could be happily ported to Linux. With that idea in mind, I went through and tested the error-reporting behavior for each math function, and filed a series of bug reports that document deviations from that ideal.

In order to get an overview, the table below summarizes the situation for all of the math functions as at glibc 2.8. The third and fourth columns indicate whether errno is correctly set and an exception is raised for each error case.































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































FunctionExpected errorerrno set correctly?Exception correctly raised?Notes
acos(+-inf)domainyy-
acosh(x<1)domainyy-
asin(+-inf)domainyy-
asinh()---No errors occur
atan()---No errors occur
atan2()---No errors occur
atanh(+-1)polenyerrno is set to EDOM (should be ERANGE)
atanh(x>1)domainyy-
cbrt()---No errors occur
ceil()---No errors occur
cos(+-inf)domainny-
cosh(+-large)overflowyye.g., cosh(DBL_MAX)
erf(+-small)underflownyFor subnormal x
erfc(x)underflownyResult underflows but produces representable (i.e., subnormal) result; e.g., erfc(27)
exp(+large)overflowyy-
exp(-large)underflowyy-
exp10(+large)overflowyyGNU extension, but inconsistent with exp()
exp10(-large)underflownyGNU extension, but inconsistent with exp()
exp2(+large)overflowyy-
exp2(-large)underflowyy-
expm1(+large)overflowny-
fabs()---No errors occur
fdim()overflownye.g., fdim(DBL_MAX, -DBL_MAX)
floor()---No errors occur
fma()domainnyVarious causes, e.g., one of x or y is an infinity and the other is 0.
fma()overflownye.g., fma(DBL_MAX, DBL_MAX, 0)
fma()underflownye.g., fma(DBL_MIN, DBL_MIN, 0)
fmax()---No errors occur
fmin()---No errors occur
fmod(+-inf,y)domainny-
fmod(x,0)domainyy-
hypot()overflowyye.g., hypot(DBL_MAX, DBL_MAX)
hypot()underflownye.g., if both arguments are small subnormal numbers
ilogb(+-inf)domainnnDoes correctly return INT_MAX
ilogb(0)domainnyDoes correctly return FP_ILOGB0
ilogb(nan)domainnyDoes correctly return FP_ILOGBNAN
j0()underflowyne.g., j0(DBL_MAX)
j1()underflowyn-
jn()underflowyn-
ldexp(x, +large-exp)overflowyy-
ldexp(x, -large-exp)underflowyy-
lgamma()overflowyye.g., lgamma(DBL_MAX)
lgamma()polenyOccurs when x is a non-positive integer; errno is set to EDOM (should be ERANGE)
llrint()domainnyx is NaN, infinity, or too large to store in a long long
llround()domainnyx is NaN, infinity, or too large to store in a long long
log(0)poleyy-
log(x<0)domainyy-
log10(0)poleyy-
log10(x<0)domainyy-
log1p(-1)poleny-
log1p(x<-1)domainny-
log2(0)poleyy-
log2(x<0)domainyy-
logb(0)poleny-
lrint()domainnyx is NaN, infinity, or too large to store in a long
lround()domainnyx is NaN, infinity, or too large to store in a long
nearbyint()---No errors occur
nextafter()overflownye.g., nextafter(DBL_MAX, +inf)
nextafter()underflownye.g., nextafter(DBL_MIN, 0);
nexttoward()overflownye.g., nexttoward(DBL_MAX, +inf)
nexttoward()underflownye.g., nexttoward(DBL_MIN, 0);
pow(0, -y)pole (0, neg)nyerrno is set to EDOM (should be ERANGE)
pow(x,y)overflowyy

Suitable values to cause overflow (e.g., pow(2, 1e100))

pow(x,y)underflowyy

Suitable values to cause underflow (e.g., pow(2, -1e100)

pow(x<0,>

domainyy-
remainder(+-inf,y)domainny-
remainder(x,0)domainyy-
remquo(+-inf,y)domainny-
remquo(x,0)domainny-
rint()---No errors occur
round()---No errors occur
scalb()overflownye.g., scalb(DBL_MAX, 200)
scalb()underflownye.g., scalb(DBL_MAX, -200)
scalb(0,+inf)domainny-
scalbln()overflownye.g., scalbln(DBL_MAX, 200)
scalbln()underflownye.g., scalbln(DBL_MAX, -200)
scalbn()overflownye.g., scalbn(DBL_MAX, 200)
scalbn()underflownye.g., scalbn(DBL_MAX, -200)
sin(+-inf)domainny-
sinh(+-large)overflowy-e.g., sinh(DBL_MAX)
sqrt(x<0)domainyy-
tan(+-inf)domainny-
tan(pi/2)overflow--No test possible, since the best approximation of pi/2 in double precision only yields a tan() value of 1.633e16.
tanh()---No errors occur
tgamma()underflownyOccurs for ranges of x values between negative integers, e.g., tgamma(-10000.5)
tgamma(+-0)poleyy-
tgamma(+large)overflowyy-
tgamma(-inf)domainny

Note the difference from
tgamma(x<0)

tgamma(x<0)domainyyFor finite x
trunc()---No errors occur
y0()overflow--Not possible to overflow with double
y0()underflowyne.g., y0(DBL_MAX)
y0(0)polennerrno is set to EDOM (should be ERANGE)
y0(x<0)domainyy-
y1()overflow--Not possible to overflow with double
y1()underflowyne.g., y1(DBL_MAX)
y1(0)polennerrno is set to EDOM (should be ERANGE)
y1(x<0)domainyy-
yn()overflownye.g., yn(1000, DBL_MIN)
yn()underflowyne.g., yn(10, DBL_MAX)
yn(0)polennerrno is set to EDOM (should be ERANGE)
yn(x<0)domainyy-

Tuesday, August 5, 2008

man-pages-3.06 is released

I've uploaded man-pages-3.06 into the release directory (or view the online pages). The main changes in man-pages-3.06 are updates to around 65 math pages. The changes are broadly as follows:
  • RETURN VALUE: in many cases, the math pages lacked descriptions of the return value when the function arguments are special cases such as +0, -0, NaN (not-a-number), +infinity, -infinity, etc. This has been fixed. I carried out tests on glibc 2.8 to ensure that the behavior of all of these functions matches the RETURN VALUE descriptions (and the POSIX.1-2001 requirements).
  • BUGS: a BUGS sections was added to a few pages to document deviations from from expected behavior.
  • ERRORS: many pages lacked a clear (or indeed any) description of how errno is set on error and what exception is raised for each error. This has been fixed. The ERRORS sections are now generally headed up as per the POSIX.1 way of doing things, describing Pole, Range, and Domain errors, as applicable. I carried out tests on glibc 2.8 to ensure that all of these functions match the ERRORS descriptions. Deviations from POSIX.1-2001 requirements have been filed as glibc bug reports, and noted in the man pages. (The pages now describe the situation for ERRORS as at glibc 2.8. I may eventually try and extend the text with descriptions of changes in older versions of glibc; watch for a post on that subject in the next days, when I'll describe my test scripts.)
  • Fixed feature test macros (FTMs). Often, the FTM requirements for the float and long double versions of a math function are different from the requirements for the double version. Each math page now shows the correct FTM requirements for all three versions of the function(s) it describes. This may have required either a change to the existing FTM text (if the requirements for the double function were already described), or the addition of an FTM description to a SYNOPSIS where one was not previously present (typically because the double version of the function does not require any FTMs to be defined). A few outright errors in the documentation of FTM requirements were also fixed.
  • CONFORMING TO: in many cases, POSIX.1-2001 was not mentioned. Where a function is specified in POSIX.1-2001, this is now noted. Also, statements about what other standards a function conforms to were generally clarified. (The wording about which functions conformed to C99 was previously often done as an add-on sentence; now it is made part of the first sentence of the CONFORMING TO section, along with mention of POSIX.1-2001.)
While making all of the above changes, I split out some logically separate material from existing pages to create three new pages: erfc(3) (formerly part of erf(3)), scalbln(3) (formerly part of scalb(3)), and y0(3) (formerly part of j0(3)).

P.S. One point that is still not covered in any page is the circumstances that generate inexact (FE_INEXACT) floating-point exceptions. (The details for these exceptions are not specified in POSIX.1-2001, and I haven't gone looking for the standards that describe the details.) If anyone has thoughts on what needs to be done about this, I'm open to ideas.

Grünegg

Monday, July 28, 2008

Handling bug reports explicitly

(Thoughts after a recent mail conversation...)

As a project maintainer, it's helpful to all concerned, but most especially you, if you are as explicit as possible when handling bug reports. In other words, explain to the reporter exactly what you did to fix the problem they reported, and why you did it. (This might be as simple as saying you applied a patch written by the reporter, or showing the patch you wrote and applied, but usually that's not enough.) If you did nothing, explain why. If the report was made by email to a list, then make sure you CC the list with your explanation. If the report was via a bug-reporting facility, then make sure that your explanation goes into the facility.

This helps you because:

  • It provides a historical record that will help you remember later what you did and why, and allow others to go back and find that information.
  • It encourages your good bug reporters to make future reports, because they can see that their reports make a difference.
  • It will help your bad bug reporters make better reports in the future.
  • Perhaps most importantly... You'll always make mistakes (misunderstand the report, make the wrong fix, etc.): if you let as many people as possible (the reporter, readers of the mailing list to which the bug report was written, followers of traffic on the bug reporting facility) know as precisely as possible what you did, then you give them all a chance to spot your mistake. I've had (far too) many of my mistakes spotted by others by explicitly explaining what I've done. (People could always find out what you did by hunting down diffs in a source repository, or a tarball, or whatever, but the effort involved means that many people won't do that.)
It helps others because:
  • The reporter of the bug knows how their problem got fixed.
  • If you are an upstream package maintainer, it will help downstream maintainers know what you did and why.
  • If you are a downstream package maintainer, it will help the upstream maintainer know what you did and why, which will help them decide whether to integrate your downstream changes upstream. 
(2012-03-25: Edit to fix a minor wording problem.)

Wednesday, July 23, 2008

man-pages-3.05 is released

I've uploaded man-pages-3.05 into the release directory (or view the online pages). Notable changes in man-pages-3.05 are:

  • A new math_error(7) page describes how to diagnose errors when calling math functions.
  • A new matherr(3) page describes the older SVID-specified mechanism for diagnosing errors from math functions.

There are a few other minor changes, but this week's release is indeed smaller than usual. That's because I'm working on pending changes to almost all of the math man pages to improve: the discussion of return values, treatment of special values (+0, -0, infinities, NaN), and error diagnostics; the accuracy of the description of feature test macro requirements; and various other details. Expect a (very) big release next week.

Blick auf die Grünegg, Konolfingen

Wednesday, July 16, 2008

Capabilities have fully arrived, finally

Linux 2.6.26 is out, which means that a complete Linux capabilities implementation has finally arrived, since we now have:

  • The ability to attach capability sets to files (added in 2.6.24), so that a process can acquire capabilities during an execve(2).
  • A CAP_SETPCAP capability with the proper semantics (since 2.6.25).
  • A per-thread capability bounding set (added in 2.6.25).
  • The per-thread securebits flags (added in 2.6.26), which can be used to restrict a thread and its children to a pure capabilities-only environment (i.e., one in which there is no special treatment of UID 0).
All of the details are provided in the recently revised capabilities(7) man page. A couple of other useful places to look for information on capabilities are Serge Hallyn's article, POSIX file capabilities: Parceling the power of root, and Chris Friedhoff's page on capabilities.

(2012-02-20: updated link to Serge Hallyn's article.)

man-pages-3.04 is released

I've uploaded man-pages-3.04 into the release directory (or view the online pages). Notable changes in man-pages-3.04 are:

  • A new utimensat(2) page describes the utimensat() system call (new in kernel 2.6.22, fixed in 2.6.26) and the futimens() library function.
  • A new end(3) page describes the end, etext, and edata variables.
  • The capget(2) page was updated by Andrew Morgan, in line with changes in Linux capabilities in kernels 2.6.24, 2.6.25, and 2.6.26.
  • The capabilities(7) page adds discussion of: file capabilities (new in Linux 2.6.24), the per-thread capability bounding set (new in Linux 2.6.25); the changed semantics for CAP_SETPCAP (Linux 2.6.25); per-thread securebits flags (new in Linux 2.6.26); three new capabilities, CAP_MAC_ADMIN, CAP_MAC_OVERRIDE, CAP_SETFCAP (Linux 2.6.25); historical CAP_SETPCAP semantics; the rules governing changes to capability sets; and the rationale for the inheritable set and capability bounding set. There were also many other more minor changes to this page. Thanks to Serge Hallyn for his contributions here.
  • The getrusage(2) page adds a description of the RUSAGE_THREAD option, which is new in Linux 2.6.26.
  • Many changes were made to the prctl(2) page, including adding documentation of: PR_CAPBSET_READ and PR_CAPBSET_DROP (thanks to Serge Hallyn); PR_GET_TSC and PR_SET_TSC (thanks to Erik Bosman); PR_SET_SECCOMP and PR_GET_SECCOMP; and PR_SET_SECUREBITS and PR_GET_SECUREBITS.
  • The proc(5) page adds documentation of /proc/config.gz (new in kernel 2.6); /proc/sys/vm/oom_kill_allocating_task (new in Linux 2.6.24); /proc/sys/vm/oom_dump_tasks (new in Linux 2.6.25); and /proc/sys/vm/panic_on_oom (new in Linux 2.6.18).
  • The getopt(3) page adds details on the use of optind for restarting an argument list scan.
  • The memchr(3) page adds a description of rawmemchr().
  • There were also very many minor content and and minor and major formatting fixes, many of them triggered by the around 70 mailed reports that I received from the Alain Portal, the French translator of man-pages. (Alain also provided dozens of reports that led to fixes in man-pages-3.03.) Thanks Alain!

Tuesday, July 8, 2008

man-pages-3.03 is released

I've uploaded man-pages-3.03 into the release directory (or view the online pages). Notable changes in man-pages-3.03 are:

  • A new cpuset(7) page, written by Paul Jackson, describes the cpuset file system, the mechanism introduced in Linux 2.6.12 for confining processes to designated processors and nodes. This enormous page becomes the fourth largest in man-pages. Thanks for a great contribution Paul!

  • A new getcpu(2) page, written by Andi Kleen, to document the getcpu(2) system call, introduced in Linux 2.6.19.

  • A new sched_getcpu(3) page documents a glibc wrapper for getcpu(2).

  • The readdir(3) page adds a description of readdir_r(3), the reentrant analog of readdir(3).

  • The signal(7) page adds a section on system call restarting (SA_RESTART), and describes the aberrant Linux behavior whereby a stop signal plus SIGCONT can interrupt some system calls, even if no signal handler has been established.

Wednesday, July 2, 2008

man-pages-3.02 is released

I've uploaded man-pages-3.02 into the release directory (or view the online pages).

Notable changes in man-pages-3.02 are:

  • A new clock_nanosleep(2) page, describing the system call introduced in kernel 2.6.

  • A rewritten getgrouplist(3) page, which provides additional information and an example program.

  • A new getutmp(3) page documenting the getutmp(3) and getutmpx(3) functions.

  • A new gnu_get_libc_version(3) page documenting get_gnu_libc_version(3) and get_gnu_libc_release(3).

  • A new sigwait(3) page documenting the sigwait(3) library function.

  • A new shm_overview(7) page providing an overview of the POSIX shared memory API.

  • Additional information in the sigreturn(2) man page.

  • Additions and updates to various pages describing the login accounting APIs, including: a new getutmp(3) page documenting the getutmp(3) and getutmpx(3) functions; and various improvements in the getutent(3) and utmp(5) pages.
2014-05-21: Some typos fixed