Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <434D0880.8070105@byu.net> Date: Wed, 12 Oct 2005 06:58:40 -0600 From: Eric Blake User-Agent: Mozilla Thunderbird 1.0.2 (Windows/20050317) MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: mkdir(2) bug [Was: please test: coreutils-5.90-2] References: <433F5562 DOT 1060806 AT byu DOT net> <434C3906 DOT 6090304 AT acm DOT org> <434C8100 DOT 9010503 AT byu DOT net> <20051012074755 DOT GU12938 AT calimero DOT vinschen DOT de> In-Reply-To: <20051012074755.GU12938@calimero.vinschen.de> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes -----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 #include #include #include 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 , 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 AT byu DOT 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/