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 From: Chris Faylor Date: Sat, 25 Dec 1999 12:36:14 -0500 To: Kazuhiro Fujieda Cc: cygwin-developers AT sourceware DOT cygnus DOT com Subject: Re: symlink() bug + patch Message-ID: <19991225123614.A13197@cygnus.com> Mail-Followup-To: Kazuhiro Fujieda , cygwin-developers AT sourceware DOT cygnus DOT com References: <00F8D6E8AB0DD3118F1A006008186C9607C7EC AT server1 DOT axonet DOT com DOT au> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0i In-Reply-To: ; from fujieda@jaist.ac.jp on Sat, Dec 25, 1999 at 04:43:15PM +0900 Applied. I especially like the fact that you used CreateFile/WriteFile rather than using open/_write. There was no need for the extra overhead in this case. Thanks, cgf On Sat, Dec 25, 1999 at 04:43:15PM +0900, Kazuhiro Fujieda wrote: >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; > }