This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mkdir(2) bug [Was: please test: coreutils-5.90-2]


-----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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]