This is the mail archive of the
cygwin-developers@sourceware.cygnus.com
mailing list for the Cygwin project.
Re: symlink() bug + patch
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 <fujieda@jaist.ac.jp>
| HOKURIKU School of Information Science
o_/ 1990 Japan Advanced Institute of Science and Technology