This is the mail archive of the cygwin-developers@sourceware.cygnus.com 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]

Re: symlink() bug + patch


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;
> 	}

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