public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Re: mkdir(2) bug [Was: please test: coreutils-5.90-2]
@ 2005-10-12 14:27 Eric Blake
  0 siblings, 0 replies; 4+ messages in thread
From: Eric Blake @ 2005-10-12 14:27 UTC (permalink / raw)
  To: cygwin

> On Oct 12 06:58, Eric Blake wrote:
> > I see the following bugs:
> > 
> > $ ./foo //   # should fail with EEXIST, not EROFS; no Windows call made
> 
> We had this already.  There's no such thing as a "correct" order of error
> messages.  EROFS is as correct as EEXIST.  If coreutils don't allow
> different correct error messages to be returned, than coreutils is just
> not foolproof enough.  If this isn't a problem with coreutils, than the
> better.

OK, for //, you win - POSIX requires EROFS ONLY if the PARENT directory
is read only, but the parent of // is //.  Fortunately, mkdir -p never
tries to do mkdir("//").

> 
> > $ ./foo /proc    # should fail with EEXIST, not EROFS
> > /proc: 30 Read-only file system
> 
> See above.

But for /proc, you are wrong - the parent directory / is not read
only, so POSIX only allows mkdir("/proc") to fail with EEXIST
and not EROFS.

> 
> > $ ./foo c:   # should fail with EEXIST, not EACCES
> 
> See my previous mail on this subject.

Isn't it just a matter of checking if the original filename was
a drive letter (a simple string comparison, no windows calls
at all), and only on the error path of EACCESS (so it won't
penalize the normal successful path)?

> 
> > $ ./foo a/.   # should fail with EEXIST, not ENOENT
> > a/.: 2 No such file or directory
> 
> I get ENOENT on Linux.

When? Before or after a exists?  It makes a difference (this
trace is on Solaris 8):

% ls a
ls: a: No such file or directory
% ./foo a/.
a/.: 2 No such file or directory
% ./foo a/
a/: 0 Error 0
% ./foo a/.
a/.: 17 File exists

Cygwin is blindly returning ENOENT, without first checking
whether a/ exists.  ENOENT is only permitted if a doesn't
exist; otherwise it must be EEXIST.

--
Eric Blake



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: mkdir(2) bug [Was: please test: coreutils-5.90-2]
@ 2005-10-12 14:33 Eric Blake
  0 siblings, 0 replies; 4+ messages in thread
From: Eric Blake @ 2005-10-12 14:33 UTC (permalink / raw)
  To: cygwin

> > On Oct 12 06:58, Eric Blake wrote:
> > > I see the following bugs:
> > > 
> > > $ ./foo //   # should fail with EEXIST, not EROFS; no Windows call made
> > 
> > We had this already.  There's no such thing as a "correct" order of error
> > messages.  EROFS is as correct as EEXIST.  If coreutils don't allow
> > different correct error messages to be returned, than coreutils is just
> > not foolproof enough.  If this isn't a problem with coreutils, than the
> > better.
> 
> OK, for //, you win - POSIX requires EROFS ONLY if the PARENT directory
> is read only, but the parent of // is //.  Fortunately, mkdir -p never
> tries to do mkdir("//").

Followup - this behavior of returning EROFS breaks
mkdir -p //server/share in 5.90.  Returning EEXIST really would be more
appropriate, but I will file an upstream bug to see whether they agree
that EROFS should be treated as a reason to call stat() to see if it
should have been EEXIST, rather than blindly failing on EROFS (this
affects non-cygwin systems, too, since you can mount writable
directories inside a read-only system).

--
Eric Blake



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: mkdir(2) bug [Was: please test: coreutils-5.90-2]
  2005-10-12 12:58         ` mkdir(2) bug [Was: please test: coreutils-5.90-2] Eric Blake
@ 2005-10-12 14:13           ` Corinna Vinschen
  0 siblings, 0 replies; 4+ messages in thread
From: Corinna Vinschen @ 2005-10-12 14:13 UTC (permalink / raw)
  To: cygwin

On Oct 12 06:58, Eric Blake wrote:
> I see the following bugs:
> 
> $ ./foo //   # should fail with EEXIST, not EROFS; no Windows call made
> //: 30 Read-only file system
> $ strace ./foo // | grep -B3 mkdir
>    65   18986 [main] foo 3788 build_fh_pc: fh 0x6115AE1C
>    34   19020 [main] foo 3788 path_conv::check: \\ is on a read-only
> filesystem
>    29   19049 [main] foo 3788 __set_errno: fhandler_base*
> build_fh_name(const char*, void*, unsigned int, suffix_info*):347 val 30
>    29   19078 [main] foo 3788 mkdir: got 30 error from build_fh_name
>    27   19105 [main] foo 3788 __set_errno: int mkdir(const char*,
> mode_t):274 val 30
>    64   19169 [main] foo 3788 mkdir: -1 = mkdir (//, 511)

We had this already.  There's no such thing as a "correct" order of error
messages.  EROFS is as correct as EEXIST.  If coreutils don't allow
different correct error messages to be returned, than coreutils is just
not foolproof enough.  If this isn't a problem with coreutils, than the
better.

> $ ./foo c:   # should fail with EEXIST, not EACCES
> c:: 13 Permission denied
> $ strace ./foo c: | grep -B3 mkdir
>    69  141826 [main] foo 1368 seterrno_from_win_error:
> /netrel/src/cygwin-snapshot-20051003-1/winsup/cygwin/fhandler_disk_file.cc:1225
> windows error 5
>    43  141869 [main] foo 1368 geterrno_from_win_error: windows error 5 ==
> errno 13
>    28  141897 [main] foo 1368 __set_errno: void
> seterrno_from_win_error(const char*, int, DWORD):310 val 13
>    54  141951 [main] foo 1368 mkdir: -1 = mkdir (c:, 511)

See my previous mail on this subject.

> $ ./foo /proc    # should fail with EEXIST, not EROFS
> /proc: 30 Read-only file system

See above.

> $ ./foo a/.   # should fail with EEXIST, not ENOENT
> a/.: 2 No such file or directory

I get ENOENT on Linux.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat, Inc.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* mkdir(2) bug [Was: please test: coreutils-5.90-2]
  2005-10-12  7:48       ` Corinna Vinschen
@ 2005-10-12 12:58         ` Eric Blake
  2005-10-12 14:13           ` Corinna Vinschen
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Blake @ 2005-10-12 12:58 UTC (permalink / raw)
  To: cygwin

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Corinna Vinschen on 10/12/2005 1:47 AM:
>>I am suspecting a cygwin bug here.  mkdir("c:") should fail with EEXIST,
>>not EACCES.  5.90 exposes this bug, where 5.3.0 did not, because the
>>algorithm for mkdir -p was changed to attempt mkdir() first instead of stat().

With this simple program:

#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>

int
main (int argc, char* argv[])
{
  int i;
  if (argc == 1)
    argc = 2; /* pass NULL */
  for (i = 1; i < argc; i++)
    {
      errno = 0;
      mkdir (argv[i], S_IRWXU|S_IRWXG|S_IRWXO);
      printf("%s: %d %s\n", argv[i] ? argv[i] : "NULL", errno,
             strerror(errno));
    }
  return 0;
}

I see the following bugs:

$ ./foo //   # should fail with EEXIST, not EROFS; no Windows call made
//: 30 Read-only file system
$ strace ./foo // | grep -B3 mkdir
   65   18986 [main] foo 3788 build_fh_pc: fh 0x6115AE1C
   34   19020 [main] foo 3788 path_conv::check: \\ is on a read-only
filesystem
   29   19049 [main] foo 3788 __set_errno: fhandler_base*
build_fh_name(const char*, void*, unsigned int, suffix_info*):347 val 30
   29   19078 [main] foo 3788 mkdir: got 30 error from build_fh_name
   27   19105 [main] foo 3788 __set_errno: int mkdir(const char*,
mode_t):274 val 30
   64   19169 [main] foo 3788 mkdir: -1 = mkdir (//, 511)

$ ./foo c:   # should fail with EEXIST, not EACCES
c:: 13 Permission denied
$ strace ./foo c: | grep -B3 mkdir
   69  141826 [main] foo 1368 seterrno_from_win_error:
/netrel/src/cygwin-snapshot-20051003-1/winsup/cygwin/fhandler_disk_file.cc:1225
windows error 5
   43  141869 [main] foo 1368 geterrno_from_win_error: windows error 5 ==
errno 13
   28  141897 [main] foo 1368 __set_errno: void
seterrno_from_win_error(const char*, int, DWORD):310 val 13
   54  141951 [main] foo 1368 mkdir: -1 = mkdir (c:, 511)

$ ./foo /proc    # should fail with EEXIST, not EROFS
/proc: 30 Read-only file system

$ mkdir a
$ ./foo a     # gives correct failure
a: 17 File exists
$ ./foo a/.   # should fail with EEXIST, not ENOENT
a/.: 2 No such file or directory
$ strace ./foo a/. | grep -B3 mkdir
   80   17961 [main] foo 760 dll_crt0_1: user_data->main 0x401050
   33   17994 [main] foo 760 __set_errno: void dll_crt0_1(char*):894 val 0
   29   18023 [main] foo 760 wait_for_sigthread: wait_sig_inited 0x71C
  117   18140 [main] foo 760 __set_errno: int mkdir(const char*,
mode_t):264 val 2


But this worked:
$ ./foo j:    # j: is a remote FAT drive, gives correct failure
j:: 17 File exists
$ strace ./foo j: | grep -B3 mkdir
  256   18952 [main] foo 3044 seterrno_from_win_error:
/netrel/src/cygwin-snapshot-20051003-1/winsup/cygwin/fhandler_disk_file.cc:1225
windows error 183
   76   19028 [main] foo 3044 geterrno_from_win_error: windows error 183
== errno 17
   30   19058 [main] foo 3044 __set_errno: void
seterrno_from_win_error(const char*, int, DWORD):310 val 17
  301   19359 [main] foo 3044 mkdir: -1 = mkdir (j:, 511)


>>
>>Continuing the example, I also find it odd that from WinXP, I get EBADRQC
>>instead of the more familiar ENOENT when removing a nonexistant directory
>>on a remote FAT drive:
> 
> 
> The error codes returned from a remote FAT filesystem on a 9x based
> host are for some reason entirely different than the error codes you'd
> expect from other experiences.
> 
> In both of the above cases, it would be helpful to run mkdir under
> strace and search for the Win32 error number, usually in a line with
> `geterrno_from_win_error' in it.

Modifying the above program in the obvious way (#include <unistd.h>, then
call rmdir() instead of mkdir()), shows the following bug (but in general,
most everything I threw at rmdir() worked):

$ ./foo j:/dir    # j:/dir doesn't exist, should fail with ENOENT
j:/dir: 54 Invalid request code
$ strace ./foo j:/dir 2>&1 |grep -B3 rmdir
 1071   28665 [main] foo 5812 seterrno_from_win_error:
/netrel/src/cygwin-snapshot-20051003-1/winsup/cygwin/fhandler_disk_file.cc:1290
windows error 1
  110   28775 [main] foo 5812 geterrno_from_win_error: windows error 1 ==
errno 54
   42   28817 [main] foo 5812 __set_errno: void
seterrno_from_win_error(const char*, int, DWORD):310 val 54
   33   28850 [main] foo 5812 rmdir: -1 = rmdir (j:/dir)

- --
Life is short - so eat dessert first!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFDTQiA84KuGfSFAYARAgwNAJ9ft0m9h5IqTtwIFnuDNQpsrQdLGQCfcYy5
EeGxcdmOfdl1uRA3wGvWPIs=
=WYdm
-----END PGP SIGNATURE-----

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-10-12 14:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-10-12 14:27 mkdir(2) bug [Was: please test: coreutils-5.90-2] Eric Blake
  -- strict thread matches above, loose matches on Subject: below --
2005-10-12 14:33 Eric Blake
2005-10-02  3:35 please test: coreutils-5.90-1 Eric Blake
2005-10-09  2:30 ` please test: coreutils-5.90-2 Eric Blake
2005-10-11 22:13   ` David Rothenberger
2005-10-12  3:20     ` Eric Blake
2005-10-12  7:48       ` Corinna Vinschen
2005-10-12 12:58         ` mkdir(2) bug [Was: please test: coreutils-5.90-2] Eric Blake
2005-10-12 14:13           ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).