Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com To: cygwin-developers AT sourceware DOT cygnus DOT com Subject: Re: symlink() bug + patch References: <00F8D6E8AB0DD3118F1A006008186C9607C7EC AT server1 DOT axonet DOT com DOT au> Mime-Version: 1.0 (generated by tm-edit 7.106) Content-Type: text/plain; charset=US-ASCII From: Kazuhiro Fujieda Date: 25 Dec 1999 16:43:15 +0900 In-Reply-To: Kazuhiro Fujieda's message of 23 Dec 1999 23:01:52 +0900 Message-ID: Lines: 76 X-Mailer: Gnus v5.3/Emacs 19.34 The following patch against the latest snapshot really makes symlink() cause EEXIST if the `frompath' is already a file or a symlink. --- path.cc- Sun Dec 19 13:57:13 1999 +++ path.cc Sat Dec 25 16:24:29 1999 @@ -1983,10 +1983,17 @@ extern "C" int symlink (const char *topath, const char *frompath) { - int fd; + HANDLE h; int res = -1; - syscall_printf ("symlink (%s, %s)", topath, frompath); + path_conv win32_path (frompath, SYMLINK_NOFOLLOW); + if (win32_path.error) + { + set_errno (win32_path.error); + goto done; + } + + syscall_printf ("symlink (%s, %s)", topath, win32_path.get_win32 ()); if (topath[0] == 0) { @@ -1999,25 +2006,35 @@ symlink (const char *topath, const char goto done; } - fd = _open (frompath, O_WRONLY | O_CREAT | O_BINARY | O_EXCL, 0); - if (fd >= 0) + if (win32_path.is_device () || + win32_path.file_attributes () != (DWORD) -1) + { + set_errno (EEXIST); + goto done; + } + + h = CreateFileA(win32_path.get_win32 (), GENERIC_WRITE, 0, &sec_none_nih, + CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); + if (h == INVALID_HANDLE_VALUE) + __seterrno (); + else { char buf[sizeof (SYMLINK_COOKIE) + MAX_PATH + 10]; __small_sprintf (buf, "%s%s", SYMLINK_COOKIE, topath); - int len = strlen (buf) + 1; + DWORD len = strlen (buf) + 1; /* Note that the terminating nul is written. */ - if (_write (fd, buf, len) != len) + DWORD written; + if (!WriteFile (h, buf, len, &written, NULL) || written != len) { - int saved_errno = get_errno (); - _close (fd); - _unlink (frompath); - set_errno (saved_errno); + __seterrno (); + CloseHandle (h); + DeleteFileA (win32_path.get_win32 ()); } else { - _close (fd); + CloseHandle (h); chmod (frompath, S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO); res = 0; } ____ | AIST Kazuhiro Fujieda | HOKURIKU School of Information Science o_/ 1990 Japan Advanced Institute of Science and Technology