[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] ls: issue error message on removed directory

From: Pádraig Brady
Subject: Re: [PATCH] ls: issue error message on removed directory
Date: Wed, 12 Feb 2020 13:38:53 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:73.0) Gecko/20100101 Thunderbird/73.0

On 12/02/2020 11:56, Bernhard Voelker wrote:
On 2/11/20 8:41 PM, Pádraig Brady wrote:
On 11/02/2020 10:45, Colin Watson wrote:
If the current directory has been removed, then "ls" confusingly
produced no output and no error message, indistinguishable from the case
of running on an empty directory.  It makes more sense to report ENOENT
in this case.

I don't think this is a general solution as the opendir() spec states:
"The directory entries for dot and dot-dot are optional".
I've also seen reference to FUSE file systems that don't provide those entries.

ls(1) does already run into ENOENT:

    $ strace /usr/bin/ls
    fstat(3, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
    getdents64(3, 0x55d8a0813f30, 32768)    = -1 ENOENT (No such file or 
    close(3)                                = 0
    close(1)                                = 0
    close(2)                                = 0
    exit_group(0)                           = ?
    +++ exited with 0 +++

... so it seems that it only swallows errno, doesn't it?

Well it's readdir() in libc that's swallowing it (as per POSIX).
As mentioned previously, we should be able to query again like:

  if (syscall(SYS_getdents, dirfd (dirp), NULL, 0) != EINVAL)
      file_failure (command_line_arg, _("reading directory %s"), name);

(note ENOENT is checked before EINVAL in the implementation,
and handling EINVAL like that simplifies the buffer considerations).

Also considering breaking shell scripts, I think this OK
as logic like the following would still work:

  [ $(ls | wc -l) = 0 ] && exit  # dir gone away


reply via email to

[Prev in Thread] Current Thread [Next in Thread]