Subject: Re: bug#8420: dirname

From: Eric Blake <[email-masked]>
Date: Mon, 04 Apr 2011 11:52:48 -0600

On 04/04/2011 11:23 AM, Bjartur Thorlacius wrote:
> You should probably not be using $0, as it doesn't contain a pathname.
> 
> Nonetheless, I believe there's truly a bug.
> Retyped from the manual for dirname 8.5:
> SYNOPSIS
>    dirname NAME
>    dirname OPTION
> While simple, this doesn't describe the GNU implementation, which is more like:
>    dirname -- NAME
>    dirname OPTION
> where OPTION begins with a hyphen or two.
> The '97 SUS 2 spec has the most simple synopsis:
>    dirname string

Coreutils complies with SUSv2, as well as SUSv3 (POSIX 2001) and SUSv4
(POSIX 2008).  Remember, POSIX states that _any_ standardized app _may_,
but not _must_, accept options unless explicitly documented otherwise
(as is the case for 'echo'); and therefore, all compliant apps not
documented otherwise _must_ accept -- for end-of-options, and all
compliant clients _must_ supply -- if they expect that the first
argument might begin with a -.  All of this without having to explicitly
document -- on every utility, because it was documented globally instead.

> 
> GNU dirname 8.5 (and some earlier versions) and FreeBSD dirname as
> shipped with an  OS X 10.4 fail to filter strings starting with an
> ASCII hyphen-minus, followed by one or more characters.

Please give a demonstration of an actual situation to back up your
assertion of a bug; until you do that, I have to assume that your test
is flawed and that GNU coreutils is standard-compliant.

> FreeBSD
> dirname conformingly fails with exit code 1 (presumably EXIT_FAILURE)
> in all cases except if argv[1] is "--", in which case both GNU and
> FreeBSD dirname ignore it, and use argv[2] instead. As does GNU
> dirname 8.5, except for the strings "--version" and "--help", in which
> case it writes non-conforming user messages to stdout and exits
> successfully.

The options --version and --help are _explicitly_ standards-conforming
extensions.  The standard requires that any application (unless
explicitly documented otherwise, as in the case of 'echo') may support
extensions to the option parsing syntax, and since the standard requires
that standardized options _only_ come from the set a-zA-VX-Z0-9 (-W is
reserved for the implementation), then the use of --xyz is an
appropriate implementation-specific extension to select the '-' short
option (which in the GNU world is in reality turning on long-option
parsing).

_ANY_ implementation of dirname that rejects 'dirname -- a' as invalid
is not standards-compliant, and the bug should be raised against that
version of dirname.

> tl;dr dirname -bash should output a single dot followed by a newline.

Wrong conclusion.  That invocation is in violation of the standards, so
it has unspecified behavior.  It _might_ output '.' if "-bash" were
treated as a filename, but the standards _also_ state that it is valid
to be treated as the "-b" option (since the standard explicitly permits
dirname to have extensions of options, even if no options are
standardized); which is exactly how GNU coreutils behaves.  The _only_
standardized way to take the dirname of "-bash" is to use "--":

dirname -- -bash

-- 
Eric Blake   [email-masked]    +1-801-349-2682
Libvirt virtualization library http://libvirt.org