/* Some utility functions.
*/
-
+/*
+ * Check if a file is writable by the current user.
+ *
+ * This is is a best effort kind of thing. It assumes a reasonable sane set
+ * of permissions by the underlying OS.
+ *
+ * We assume that basic unix permission bits are authoritative. Which might not
+ * be the case under systems with extended permissions systems (posix ACLs, SELinux, OSX/iOS sandboxing, etc)
+ *
+ * The choice of access as the fallback is due to the expected lower overhead compared to trying to open the file.
+ *
+ * The only expected problem with using access are for root, setuid or setgid programs as access is not consistent
+ * under those situations. It's to be expected that this should not happen in practice as those bits are very dangerous
+ * and should not be used with a dynamic runtime.
+ */
static gboolean
is_file_writable (struct stat *st, const char *path)
{
if ((st->st_gid == getegid ()) && (st->st_mode & S_IWGRP))
return 1;
- /* Fallback to using access(2). It's not ideal as it doesn't effective user/group
+ /* Fallback to using access(2). It's not ideal as it might not take into consideration euid/egid
* but it's the only sane option we have on unix.
*/
return access (path, W_OK) == 0;
}
#ifdef FTRUNCATE_DOESNT_EXTEND
- /* I haven't bothered to write the configure.in stuff for this
+ /* I haven't bothered to write the configure.ac stuff for this
* because I don't know if any platform needs it. I'm leaving
* this code just in case though
*/
const gunichar2 *backupFileName, guint32 replaceFlags,
gpointer exclude, gpointer reserved)
{
- int result, errno_copy, backup_fd = -1,replaced_fd = -1;
+ int result, backup_fd = -1,replaced_fd = -1;
gchar *utf8_replacedFileName, *utf8_replacementFileName = NULL, *utf8_backupFileName = NULL;
struct stat stBackup;
gboolean ret = FALSE;
// Open the backup file for read so we can restore the file if an error occurs.
backup_fd = _wapi_open (utf8_backupFileName, O_RDONLY, 0);
result = _wapi_rename (utf8_replacedFileName, utf8_backupFileName);
- errno_copy = errno;
if (result == -1)
goto replace_cleanup;
}
result = _wapi_rename (utf8_replacementFileName, utf8_replacedFileName);
- errno_copy = errno;
if (result == -1) {
_wapi_set_last_path_error_from_errno (NULL, utf8_replacementFileName);
_wapi_rename (utf8_backupFileName, utf8_replacedFileName);
handle = GINT_TO_POINTER (fd);
- pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
- (void *)&stdhandle_mutex);
thr_ret = mono_mutex_lock (&stdhandle_mutex);
g_assert (thr_ret == 0);
done:
thr_ret = mono_mutex_unlock (&stdhandle_mutex);
g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
return(handle);
}
return(FALSE);
}
- pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
- handle);
thr_ret = _wapi_handle_lock_handle (handle);
g_assert (thr_ret == 0);
cleanup:
thr_ret = _wapi_handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
return(ret);
}
return(FALSE);
}
- pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
- handle);
thr_ret = _wapi_handle_lock_handle (handle);
g_assert (thr_ret == 0);
thr_ret = _wapi_handle_unlock_handle (handle);
g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
_wapi_handle_unref (handle);
ignore_entry = TRUE;
else
ignore_entry = FALSE;
- } else
+ } else if (state->fstype_index == 3 && memcmp ("nfs", state->fstype, state->fstype_index) == 0)
+ ignore_entry = FALSE;
+ else
ignore_entry = TRUE;
if (!ignore_entry) {