[runtime] Fix multiple issues around symlink handling.
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 23 May 2017 21:46:53 +0000 (14:46 -0700)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 23 May 2017 21:46:53 +0000 (14:46 -0700)
After fixing my windows setup, I managed to properly test MS's behavior, which is a lot saner and it's the following:

Opening fails with ERROR_CANT_RESOLVE_FILENAME (1921).
Testing and Deleting works.

Fixing File.Delete required removing the lstat we do before deleting, which no longer serves any purpose.

Fixing File.Exists requires handling ELOOP when stat fails and we retry with lstat.

mono/metadata/w32error-unix.c
mono/metadata/w32error.h
mono/metadata/w32file-unix.c

index dbbc43bc6f86643cbc5ec0a5706a45490091dddc..df41473dfe896fbc0e1fbe07c82f20b00a360eeb 100644 (file)
@@ -65,7 +65,7 @@ mono_w32error_unix_to_win32 (guint32 error)
        case EIO: return ERROR_INVALID_HANDLE;
        case EINTR: return ERROR_IO_PENDING; /* best match I could find */
        case EPIPE: return ERROR_WRITE_FAULT;
-       case ELOOP: return ERROR_ACCESS_DENIED; /* Empirically found by testing desktop dotnet. */
+       case ELOOP: return ERROR_CANT_RESOLVE_FILENAME;
 
        default:
                g_error ("%s: unknown error (%d) \"%s\"", __FILE__, error, g_strerror (error));
index c8fb1717a52225a1bb1fda4186822b821fc2a1b0..439bdd81a2a0d366e5f1a3fec63ac8448cbfed49 100644 (file)
@@ -42,6 +42,7 @@
 #define ERROR_FILENAME_EXCED_RANGE 206
 #define ERROR_DIRECTORY            267
 #define ERROR_IO_PENDING           997
+#define ERROR_CANT_RESOLVE_FILENAME 1921
 #define ERROR_ENCRYPTION_FAILED    6000
 #define WSAEINTR                   10004
 #define WSAEBADF                   10009
index f6e4d2df5138873927882d9bd3cda436dcba411b..6fcb0f691f19ed0ec8c362698b4ee38fe6893e9a 100644 (file)
@@ -2518,7 +2518,6 @@ gboolean mono_w32file_delete(const gunichar2 *name)
        gchar *filename;
        gint retval;
        gboolean ret = FALSE;
-       guint32 attrs;
 #if 0
        struct stat statbuf;
        FileShare *shareinfo;
@@ -2539,14 +2538,6 @@ gboolean mono_w32file_delete(const gunichar2 *name)
                return(FALSE);
        }
 
-       attrs = mono_w32file_get_attributes (name);
-       if (attrs == INVALID_FILE_ATTRIBUTES) {
-               mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: file attributes error", __func__);
-               /* Error set by mono_w32file_get_attributes() */
-               g_free (filename);
-               return(FALSE);
-       }
-
 #if 0
        /* Check to make sure sharing allows us to open the file for
         * writing.  See bug 323389.
@@ -3748,7 +3739,7 @@ mono_w32file_get_attributes (const gunichar2 *name)
        }
 
        result = _wapi_stat (utf8_name, &buf);
-       if (result == -1 && errno == ENOENT) {
+       if (result == -1 && (errno == ENOENT || errno == ELOOP)) {
                /* Might be a dangling symlink... */
                result = _wapi_lstat (utf8_name, &buf);
        }