#include <stdio.h>
#include <utime.h>
-#ifndef PLATFORM_WIN32
-#ifdef HAVE_AIO_H
-#include <aio.h>
-#define USE_AIO 1
-#elif defined(HAVE_SYS_AIO_H)
-#include <sys/aio.h>
-#define USE_AIO 1
-#else
-#undef USE_AIO
-#endif
-#endif
-
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
static gboolean _wapi_lock_file_region (int fd, off_t offset, off_t length);
static gboolean _wapi_unlock_file_region (int fd, off_t offset, off_t length);
-static void file_close_shared (gpointer handle);
-static void file_close_private (gpointer handle);
+static void file_close (gpointer handle, gpointer data);
static WapiFileType file_getfiletype(void);
static gboolean file_read(gpointer handle, gpointer buffer,
guint32 numbytes, guint32 *bytesread,
/* File handle is only signalled for overlapped IO */
struct _WapiHandleOps _wapi_file_ops = {
- file_close_shared, /* close_shared */
- file_close_private, /* close_private */
+ file_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
};
-static void console_close_shared (gpointer handle);
-static void console_close_private (gpointer handle);
+void _wapi_file_details (gpointer handle_info)
+{
+ struct _WapiHandle_file *file = (struct _WapiHandle_file *)handle_info;
+
+ g_print ("[%20s] acc: %c%c%c, shr: %c%c%c, attrs: %5u",
+ file->filename,
+ file->fileaccess&GENERIC_READ?'R':'.',
+ file->fileaccess&GENERIC_WRITE?'W':'.',
+ file->fileaccess&GENERIC_EXECUTE?'X':'.',
+ file->sharemode&FILE_SHARE_READ?'R':'.',
+ file->sharemode&FILE_SHARE_WRITE?'W':'.',
+ file->sharemode&FILE_SHARE_DELETE?'D':'.',
+ file->attrs);
+}
+
+static void console_close (gpointer handle, gpointer data);
static WapiFileType console_getfiletype(void);
static gboolean console_read(gpointer handle, gpointer buffer,
guint32 numbytes, guint32 *bytesread,
* input or output
*/
struct _WapiHandleOps _wapi_console_ops = {
- console_close_shared, /* close_shared */
- console_close_private, /* close_private */
+ console_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
};
+void _wapi_console_details (gpointer handle_info)
+{
+ _wapi_file_details (handle_info);
+}
+
/* Find handle has no ops.
*/
struct _WapiHandleOps _wapi_find_ops = {
- NULL, /* close_shared */
- NULL, /* close_private */
+ NULL, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
};
-static void pipe_close_shared (gpointer handle);
-static void pipe_close_private (gpointer handle);
+static void pipe_close (gpointer handle, gpointer data);
static WapiFileType pipe_getfiletype (void);
static gboolean pipe_read (gpointer handle, gpointer buffer, guint32 numbytes,
guint32 *bytesread, WapiOverlapped *overlapped);
/* Pipe handles
*/
struct _WapiHandleOps _wapi_pipe_ops = {
- pipe_close_shared, /* close_shared */
- pipe_close_private, /* close_private */
+ pipe_close, /* close */
NULL, /* signal */
NULL, /* own */
NULL, /* is_owned */
};
-static struct {
+void _wapi_pipe_details (gpointer handle_info)
+{
+ _wapi_file_details (handle_info);
+}
+
+static const struct {
/* File, console and pipe handles */
WapiFileType (*getfiletype)(void);
NULL, NULL, NULL, NULL, NULL, NULL},
};
+#define NO_SIGPIPE(x) do { \
+ void (*old_sigpipe)(int) = signal (SIGPIPE, SIG_IGN); \
+ x; \
+ signal (SIGPIPE, old_sigpipe); \
+ } while (0)
static mono_once_t io_ops_once=MONO_ONCE_INIT;
/* Handle ops.
*/
-static void file_close_shared (gpointer handle)
+static void file_close (gpointer handle, gpointer data)
{
- struct _WapiHandle_file *file_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
- return;
- }
+ struct _WapiHandle_file *file_handle = (struct _WapiHandle_file *)data;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": closing file handle %p", handle);
+ g_message("%s: closing file handle %p [%s]", __func__, handle,
+ file_handle->filename);
#endif
-
- if(file_handle->filename!=0) {
- _wapi_handle_scratch_delete (file_handle->filename);
- file_handle->filename=0;
- }
- if(file_handle->security_attributes!=0) {
- _wapi_handle_scratch_delete (file_handle->security_attributes);
- file_handle->security_attributes=0;
- }
-}
-static void file_close_private (gpointer handle)
-{
- struct _WapiHandlePrivate_file *file_private_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE, NULL,
- (gpointer *)&file_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
- return;
- }
+ g_free (file_handle->filename);
-#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": closing file handle %p with fd %d",
- handle, file_private_handle->fd);
-#endif
+ _wapi_handle_share_release (file_handle->share_info);
- close(file_private_handle->fd);
+ close (GPOINTER_TO_UINT(handle));
}
static WapiFileType file_getfiletype(void)
return(FILE_TYPE_DISK);
}
-#ifdef USE_AIO
-typedef struct {
- struct aiocb *aio;
- WapiOverlapped *overlapped;
- WapiOverlappedCB callback;
-} notifier_data_t;
-
-#define SIGPTR(a) a.SIGVAL_PTR
-
-static void
-async_notifier (union sigval sig)
-{
- notifier_data_t *ndata = SIGPTR (sig);
- guint32 error;
- guint32 numbytes;
-
- error = aio_return (ndata->aio);
- if (error < 0) {
- error = _wapi_get_win32_file_error (error);
- numbytes = 0;
- } else {
- numbytes = error;
- error = 0;
- }
-
- ndata->callback (error, numbytes, ndata->overlapped);
- g_free (ndata->aio);
- g_free (ndata);
-}
-
-#endif /* USE_AIO */
-
static gboolean file_read(gpointer handle, gpointer buffer,
guint32 numbytes, guint32 *bytesread,
WapiOverlapped *overlapped)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
+ int fd = GPOINTER_TO_UINT(handle);
int ret;
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
-
+
if(bytesread!=NULL) {
*bytesread=0;
}
- if(!(file_handle->fileaccess&GENERIC_READ) &&
- !(file_handle->fileaccess&GENERIC_ALL)) {
+ if(!(file_handle->fileaccess & GENERIC_READ) &&
+ !(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_READ access: %u",
+ __func__, handle, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
- if (file_private_handle->async == FALSE) {
- do {
- ret=read(file_private_handle->fd, buffer, numbytes);
- }
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ do {
+ ret = read (fd, buffer, numbytes);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending());
- if(ret==-1) {
- gint err = errno;
-
-#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": read of handle %p fd %d error: %s", handle,
- file_private_handle->fd, strerror(err));
-#endif
- SetLastError (_wapi_get_win32_file_error (err));
- return(FALSE);
- }
-
- if(bytesread!=NULL) {
- *bytesread=ret;
- }
-
- return(TRUE);
- }
-
-#ifndef USE_AIO
- SetLastError (ERROR_NOT_SUPPORTED);
- return FALSE;
-#else
- if (overlapped == NULL || file_private_handle->callback == NULL) {
- SetLastError (ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- {
- int fd = file_private_handle->fd;
- struct aiocb *aio;
- int result;
- notifier_data_t *ndata;
-
- ndata = g_new0 (notifier_data_t, 1);
- aio = g_new0 (struct aiocb, 1);
- ndata->overlapped = overlapped;
- ndata->aio = aio;
- ndata->callback = file_private_handle->callback;
-
- aio->aio_fildes = fd;
- aio->aio_lio_opcode = LIO_READ;
- aio->aio_nbytes = numbytes;
- aio->aio_offset = overlapped->Offset + (((gint64) overlapped->OffsetHigh) << 32);
- aio->aio_buf = buffer;
- aio->aio_sigevent.sigev_notify = SIGEV_THREAD;
- aio->aio_sigevent.sigev_notify_function = async_notifier;
- SIGPTR (aio->aio_sigevent.sigev_value) = ndata;
-
- result = aio_read (aio);
- if (result == -1) {
- _wapi_set_last_error_from_errno ();
- return FALSE;
- }
+ if(ret==-1) {
+ gint err = errno;
- result = aio_error (aio);
#ifdef DEBUG
- g_print ("aio_error (read) returned %d for %d\n", result, fd);
+ g_message("%s: read of handle %p error: %s", __func__,
+ handle, strerror(err));
#endif
- if (result == 0) {
- numbytes = aio_return (aio);
-#ifdef DEBUG
- g_print ("numbytes %d for %d\n", numbytes, fd);
-#endif
- } else {
- errno = result;
- _wapi_set_last_error_from_errno ();
- return FALSE;
+ SetLastError (_wapi_get_win32_file_error (err));
+ return(FALSE);
}
-
- if (bytesread)
- *bytesread = numbytes;
-
- return TRUE;
+
+ if (bytesread != NULL) {
+ *bytesread = ret;
}
-#endif
+
+ return(TRUE);
}
static gboolean file_write(gpointer handle, gconstpointer buffer,
WapiOverlapped *overlapped G_GNUC_UNUSED)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
int ret;
+ off_t current_pos;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
*byteswritten=0;
}
- if(!(file_handle->fileaccess&GENERIC_WRITE) &&
- !(file_handle->fileaccess&GENERIC_ALL)) {
+ if(!(file_handle->fileaccess & GENERIC_WRITE) &&
+ !(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
- if (file_private_handle->async == FALSE) {
- off_t current_pos;
-
- /* Need to lock the region we're about to write to,
- * because we only do advisory locking on POSIX
- * systems
- */
- current_pos = lseek (file_private_handle->fd, (off_t)0,
- SEEK_CUR);
- if (current_pos == -1) {
+ /* Need to lock the region we're about to write to, because we
+ * only do advisory locking on POSIX systems
+ */
+ current_pos = lseek (fd, (off_t)0, SEEK_CUR);
+ if (current_pos == -1) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d lseek failed: %s", handle, file_private_handle->fd, strerror (errno));
+ g_message ("%s: handle %p lseek failed: %s", __func__, handle,
+ strerror (errno));
#endif
- _wapi_set_last_error_from_errno ();
- return(FALSE);
- }
+ _wapi_set_last_error_from_errno ();
+ return(FALSE);
+ }
- if (_wapi_lock_file_region (file_private_handle->fd,
- current_pos, numbytes) == FALSE) {
- /* The error has already been set */
- return(FALSE);
- }
+ if (_wapi_lock_file_region (fd, current_pos, numbytes) == FALSE) {
+ /* The error has already been set */
+ return(FALSE);
+ }
+ NO_SIGPIPE(
do {
- ret=write(file_private_handle->fd, buffer, numbytes);
- }
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
-
- _wapi_unlock_file_region (file_private_handle->fd, current_pos,
- numbytes);
+ ret = write (fd, buffer, numbytes);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending());
+ );
+
+ _wapi_unlock_file_region (fd, current_pos, numbytes);
- if(ret==-1) {
+ if (ret == -1) {
+ if (errno == EINTR) {
+ ret = 0;
+ } else {
+ _wapi_set_last_error_from_errno ();
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": write of handle %p fd %d error: %s", handle,
- file_private_handle->fd, strerror(errno));
+ g_message("%s: write of handle %p error: %s",
+ __func__, handle, strerror(errno));
#endif
return(FALSE);
}
- if(byteswritten!=NULL) {
- *byteswritten=ret;
- }
- return(TRUE);
}
-
-#ifndef USE_AIO
- SetLastError (ERROR_NOT_SUPPORTED);
- return FALSE;
-#else
- if (overlapped == NULL || file_private_handle->callback == NULL) {
- SetLastError (ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- {
- int fd = file_private_handle->fd;
- struct aiocb *aio;
- int result;
- notifier_data_t *ndata;
-
- ndata = g_new0 (notifier_data_t, 1);
- aio = g_new0 (struct aiocb, 1);
- ndata->overlapped = overlapped;
- ndata->aio = aio;
- ndata->callback = file_private_handle->callback;
-
- aio->aio_fildes = fd;
- aio->aio_lio_opcode = LIO_WRITE;
- aio->aio_nbytes = numbytes;
- aio->aio_offset = overlapped->Offset + (((gint64) overlapped->OffsetHigh) << 32);
- aio->aio_buf = (gpointer) buffer;
- aio->aio_sigevent.sigev_notify = SIGEV_THREAD;
- aio->aio_sigevent.sigev_notify_function = async_notifier;
- SIGPTR (aio->aio_sigevent.sigev_value) = ndata;
-
- result = aio_write (aio);
- if (result == -1) {
- _wapi_set_last_error_from_errno ();
- return FALSE;
+ if (byteswritten != NULL) {
+ *byteswritten = ret;
}
-
- result = aio_error (aio);
-#ifdef DEBUG
- g_print ("aio_error (write) returned %d for %d\n", result, fd);
-#endif
- if (result == 0) {
- numbytes = aio_return (aio);
-#ifdef DEBUG
- g_print ("numbytes %d for %d\n", numbytes, fd);
-#endif
- } else {
- errno = result;
- _wapi_set_last_error_from_errno ();
- return FALSE;
- }
-
- if (byteswritten)
- *byteswritten = numbytes;
-
- return TRUE;
- }
-#endif
+ return(TRUE);
}
static gboolean file_flush(gpointer handle)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- if(!(file_handle->fileaccess&GENERIC_WRITE) &&
- !(file_handle->fileaccess&GENERIC_ALL)) {
+ if(!(file_handle->fileaccess & GENERIC_WRITE) &&
+ !(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
- ret=fsync(file_private_handle->fd);
+ ret=fsync(fd);
if (ret==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": write of handle %p fd %d error: %s", handle,
- file_private_handle->fd, strerror(errno));
+ g_message("%s: fsync of handle %p error: %s", __func__, handle,
+ strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
gint32 *highmovedistance, WapiSeekMethod method)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
off_t offset, newpos;
int whence;
guint32 ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(INVALID_SET_FILE_POINTER);
}
- if(!(file_handle->fileaccess&GENERIC_READ) &&
- !(file_handle->fileaccess&GENERIC_WRITE) &&
- !(file_handle->fileaccess&GENERIC_ALL)) {
+ if(!(file_handle->fileaccess & GENERIC_READ) &&
+ !(file_handle->fileaccess & GENERIC_WRITE) &&
+ !(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message ("%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(INVALID_SET_FILE_POINTER);
}
break;
default:
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": invalid seek type %d",
- method);
+ g_message("%s: invalid seek type %d", __func__, method);
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(INVALID_SET_FILE_POINTER);
}
if(highmovedistance==NULL) {
offset=movedistance;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": setting offset to %lld (low %d)", offset,
- movedistance);
+ g_message("%s: setting offset to %lld (low %d)", __func__,
+ offset, movedistance);
#endif
} else {
- offset=((gint64) *highmovedistance << 32) | movedistance;
+ offset=((gint64) *highmovedistance << 32) | (unsigned long)movedistance;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": setting offset to %lld 0x%llx (high %d 0x%x, low %d 0x%x)", offset, offset, *highmovedistance, *highmovedistance, movedistance, movedistance);
+ g_message("%s: setting offset to %lld 0x%llx (high %d 0x%x, low %d 0x%x)", __func__, offset, offset, *highmovedistance, *highmovedistance, movedistance, movedistance);
#endif
}
#else
#ifdef DEBUG
#ifdef HAVE_LARGE_FILE_SUPPORT
- g_message(G_GNUC_PRETTY_FUNCTION
- ": moving handle %p fd %d by %lld bytes from %d", handle,
- file_private_handle->fd, offset, whence);
+ g_message("%s: moving handle %p by %lld bytes from %d", __func__,
+ handle, offset, whence);
#else
- g_message(G_GNUC_PRETTY_FUNCTION
- ": moving handle %p fd %d by %ld bytes from %d", handle,
- file_private_handle->fd, offset, whence);
+ g_message("%s: moving handle %p fd %d by %ld bytes from %d", __func__,
+ handle, offset, whence);
#endif
#endif
- newpos=lseek(file_private_handle->fd, offset, whence);
+ newpos=lseek(fd, offset, whence);
if(newpos==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": lseek on handle %p fd %d returned error %s",
- handle, file_private_handle->fd, strerror(errno));
+ g_message("%s: lseek on handle %p returned error %s",
+ __func__, handle, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(INVALID_SET_FILE_POINTER);
}
#ifdef DEBUG
#ifdef HAVE_LARGE_FILE_SUPPORT
- g_message(G_GNUC_PRETTY_FUNCTION ": lseek returns %lld", newpos);
+ g_message("%s: lseek returns %lld", __func__, newpos);
#else
- g_message(G_GNUC_PRETTY_FUNCTION ": lseek returns %ld", newpos);
+ g_message ("%s: lseek returns %ld", __func__, newpos);
#endif
#endif
#endif
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": move of handle %p fd %d returning %d/%d", handle,
- file_private_handle->fd, ret,
- highmovedistance==NULL?0:*highmovedistance);
+ g_message ("%s: move of handle %p returning %d/%d", __func__,
+ handle, ret, highmovedistance==NULL?0:*highmovedistance);
#endif
return(ret);
static gboolean file_setendoffile(gpointer handle)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
struct stat statbuf;
off_t size, pos;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- if(!(file_handle->fileaccess&GENERIC_WRITE) &&
- !(file_handle->fileaccess&GENERIC_ALL)) {
+ if(!(file_handle->fileaccess & GENERIC_WRITE) &&
+ !(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
* than the length, truncate the file.
*/
- ret=fstat(file_private_handle->fd, &statbuf);
+ ret=fstat(fd, &statbuf);
if(ret==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p fd %d fstat failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ g_message ("%s: handle %p fstat failed: %s", __func__,
+ handle, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
size=statbuf.st_size;
- pos=lseek(file_private_handle->fd, (off_t)0, SEEK_CUR);
+ pos=lseek(fd, (off_t)0, SEEK_CUR);
if(pos==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p fd %d lseek failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ g_message("%s: handle %p lseek failed: %s", __func__,
+ handle, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
if(pos>size) {
- /* extend */
- do {
- ret=write(file_private_handle->fd, "", 1);
- }
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ /* Extend the file. Use write() here, because some
+ * manuals say that ftruncate() behaviour is undefined
+ * when the file needs extending. The POSIX spec says
+ * that on XSI-conformant systems it extends, so if
+ * every system we care about conforms, then we can
+ * drop this write.
+ */
+ NO_SIGPIPE(
+ do {
+ ret = write (fd, "", 1);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending());
+ );
if(ret==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p fd %d extend write failed: %s",
- handle, file_private_handle->fd,
- strerror(errno));
+ g_message("%s: handle %p extend write failed: %s", __func__, handle, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
}
* byte to the end of the file
*/
do {
- ret=ftruncate(file_private_handle->fd, pos);
+ ret=ftruncate(fd, pos);
}
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
-
+ while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
if(ret==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p fd %d ftruncate failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ g_message("%s: handle %p ftruncate failed: %s", __func__,
+ handle, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
static guint32 file_getfilesize(gpointer handle, guint32 *highsize)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
struct stat statbuf;
guint32 size;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(INVALID_FILE_SIZE);
}
- if(!(file_handle->fileaccess&GENERIC_READ) &&
- !(file_handle->fileaccess&GENERIC_WRITE) &&
- !(file_handle->fileaccess&GENERIC_ALL)) {
+ if(!(file_handle->fileaccess & GENERIC_READ) &&
+ !(file_handle->fileaccess & GENERIC_WRITE) &&
+ !(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(INVALID_FILE_SIZE);
}
- ret=fstat(file_private_handle->fd, &statbuf);
- if(ret==-1) {
+ /* If the file has a size with the low bits 0xFFFFFFFF the
+ * caller can't tell if this is an error, so clear the error
+ * value
+ */
+ SetLastError (ERROR_SUCCESS);
+
+ ret = fstat(fd, &statbuf);
+ if (ret == -1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p fd %d fstat failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ g_message ("%s: handle %p fstat failed: %s", __func__,
+ handle, strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(INVALID_FILE_SIZE);
}
#ifdef HAVE_LARGE_FILE_SUPPORT
- size=statbuf.st_size & 0xFFFFFFFF;
- if(highsize!=NULL) {
- *highsize=statbuf.st_size>>32;
+ size = statbuf.st_size & 0xFFFFFFFF;
+ if (highsize != NULL) {
+ *highsize = statbuf.st_size>>32;
}
#else
- if(highsize!=NULL) {
+ if (highsize != NULL) {
/* Accurate, but potentially dodgy :-) */
- *highsize=0;
+ *highsize = 0;
}
- size=statbuf.st_size;
+ size = statbuf.st_size;
#endif
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Returning size %d/%d", size,
- *highsize);
+ g_message ("%s: Returning size %d/%d", __func__, size, *highsize);
#endif
return(size);
WapiFileTime *last_write)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
struct stat statbuf;
guint64 create_ticks, access_ticks, write_ticks;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
-
- if(!(file_handle->fileaccess&GENERIC_READ) &&
- !(file_handle->fileaccess&GENERIC_ALL)) {
+
+ if(!(file_handle->fileaccess & GENERIC_READ) &&
+ !(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_READ access: %u",
+ __func__, handle, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
- ret=fstat(file_private_handle->fd, &statbuf);
+ ret=fstat(fd, &statbuf);
if(ret==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p fd %d fstat failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ g_message("%s: handle %p fstat failed: %s", __func__, handle,
+ strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": atime: %ld ctime: %ld mtime: %ld",
+ g_message("%s: atime: %ld ctime: %ld mtime: %ld", __func__,
statbuf.st_atime, statbuf.st_ctime,
statbuf.st_mtime);
#endif
write_ticks=((guint64)statbuf.st_mtime*10000000)+116444736000000000ULL;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": aticks: %llu cticks: %llu wticks: %llu",
- access_ticks, create_ticks, write_ticks);
+ g_message("%s: aticks: %llu cticks: %llu wticks: %llu", __func__,
+ access_ticks, create_ticks, write_ticks);
#endif
if(create_time!=NULL) {
const WapiFileTime *last_write)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
- guchar *name;
struct utimbuf utbuf;
struct stat statbuf;
guint64 access_ticks, write_ticks;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- if(!(file_handle->fileaccess&GENERIC_WRITE) &&
- !(file_handle->fileaccess&GENERIC_ALL)) {
+ if(!(file_handle->fileaccess & GENERIC_WRITE) &&
+ !(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
- if(file_handle->filename==0) {
+ if(file_handle->filename == NULL) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p fd %d unknown filename", handle,
- file_private_handle->fd);
+ g_message("%s: handle %p unknown filename", __func__, handle);
#endif
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
/* Get the current times, so we can put the same times back in
* the event that one of the FileTime structs is NULL
*/
- ret=fstat(file_private_handle->fd, &statbuf);
+ ret=fstat (fd, &statbuf);
if(ret==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p fd %d fstat failed: %s", handle,
- file_private_handle->fd, strerror(errno));
+ g_message("%s: handle %p fstat failed: %s", __func__, handle,
+ strerror(errno));
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
if(last_access!=NULL) {
access_ticks=((guint64)last_access->dwHighDateTime << 32) +
last_access->dwLowDateTime;
+ /* This is (time_t)0. We can actually go to INT_MIN,
+ * but this will do for now.
+ */
+ if (access_ticks < 116444736000000000ULL) {
+#ifdef DEBUG
+ g_message ("%s: attempt to set access time too early",
+ __func__);
+#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return(FALSE);
+ }
+
utbuf.actime=(access_ticks - 116444736000000000ULL) / 10000000;
} else {
utbuf.actime=statbuf.st_atime;
if(last_write!=NULL) {
write_ticks=((guint64)last_write->dwHighDateTime << 32) +
last_write->dwLowDateTime;
+ /* This is (time_t)0. We can actually go to INT_MIN,
+ * but this will do for now.
+ */
+ if (write_ticks < 116444736000000000ULL) {
+#ifdef DEBUG
+ g_message ("%s: attempt to set write time too early",
+ __func__);
+#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return(FALSE);
+ }
+
utbuf.modtime=(write_ticks - 116444736000000000ULL) / 10000000;
} else {
utbuf.modtime=statbuf.st_mtime;
}
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": setting handle %p access %ld write %ld", handle,
- utbuf.actime, utbuf.modtime);
+ g_message("%s: setting handle %p access %ld write %ld", __func__,
+ handle, utbuf.actime, utbuf.modtime);
#endif
- name=_wapi_handle_scratch_lookup (file_handle->filename);
-
- ret=utime(name, &utbuf);
+ ret=utime(file_handle->filename, &utbuf);
if(ret==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": handle %p [%s] fd %d utime failed: %s", handle,
- name, file_private_handle->fd, strerror(errno));
+ g_message("%s: handle %p [%s] utime failed: %s", __func__,
+ handle, file_handle->filename, strerror(errno));
#endif
- g_free (name);
+ SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
-
- g_free (name);
return(TRUE);
}
-static void console_close_shared (gpointer handle)
+static void console_close (gpointer handle, gpointer data)
{
- struct _WapiHandle_file *console_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
- (gpointer *)&console_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up console handle %p", handle);
- return;
- }
+ struct _WapiHandle_file *console_handle = (struct _WapiHandle_file *)data;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": closing console handle %p", handle);
+ g_message("%s: closing console handle %p", __func__, handle);
#endif
-
- if(console_handle->filename!=0) {
- _wapi_handle_scratch_delete (console_handle->filename);
- console_handle->filename=0;
- }
- if(console_handle->security_attributes!=0) {
- _wapi_handle_scratch_delete (console_handle->security_attributes);
- console_handle->security_attributes=0;
- }
-}
-static void console_close_private (gpointer handle)
-{
- struct _WapiHandlePrivate_file *console_private_handle;
- gboolean ok;
+ g_free (console_handle->filename);
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE, NULL,
- (gpointer *)&console_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up console handle %p", handle);
- return;
- }
-
-#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": closing console handle %p with fd %d", handle,
- console_private_handle->fd);
-#endif
-
- close(console_private_handle->fd);
+ close (GPOINTER_TO_UINT(handle));
}
static WapiFileType console_getfiletype(void)
WapiOverlapped *overlapped G_GNUC_UNUSED)
{
struct _WapiHandle_file *console_handle;
- struct _WapiHandlePrivate_file *console_private_handle;
gboolean ok;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
- (gpointer *)&console_handle,
- (gpointer *)&console_private_handle);
+ (gpointer *)&console_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up console handle %p", handle);
+ g_warning ("%s: error looking up console handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
*bytesread=0;
}
- if(!(console_handle->fileaccess&GENERIC_READ) &&
- !(console_handle->fileaccess&GENERIC_ALL)) {
+ if(!(console_handle->fileaccess & GENERIC_READ) &&
+ !(console_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, console_private_handle->fd, console_handle->fileaccess);
+ g_message ("%s: handle %p doesn't have GENERIC_READ access: %u",
+ __func__, handle, console_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
do {
- ret=read(console_private_handle->fd, buffer, numbytes);
- }
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ ret=read(fd, buffer, numbytes);
+ } while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
if(ret==-1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": read of handle %p fd %d error: %s", handle,
- console_private_handle->fd, strerror(errno));
+ g_message("%s: read of handle %p error: %s", __func__, handle,
+ strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(FALSE);
}
WapiOverlapped *overlapped G_GNUC_UNUSED)
{
struct _WapiHandle_file *console_handle;
- struct _WapiHandlePrivate_file *console_private_handle;
gboolean ok;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
- (gpointer *)&console_handle,
- (gpointer *)&console_private_handle);
+ (gpointer *)&console_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up console handle %p", handle);
+ g_warning ("%s: error looking up console handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
*byteswritten=0;
}
- if(!(console_handle->fileaccess&GENERIC_WRITE) &&
- !(console_handle->fileaccess&GENERIC_ALL)) {
+ if(!(console_handle->fileaccess & GENERIC_WRITE) &&
+ !(console_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, console_private_handle->fd, console_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, console_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
- do {
- ret=write(console_private_handle->fd, buffer, numbytes);
- }
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ NO_SIGPIPE(
+ do {
+ ret = write(fd, buffer, numbytes);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending());
+ );
- if(ret==-1) {
+ if (ret == -1) {
+ if (errno == EINTR) {
+ ret = 0;
+ } else {
+ _wapi_set_last_error_from_errno ();
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": write of handle %p fd %d error: %s", handle,
- console_private_handle->fd, strerror(errno));
+ g_message ("%s: write of handle %p error: %s",
+ __func__, handle, strerror(errno));
#endif
- return(FALSE);
+ return(FALSE);
+ }
}
if(byteswritten!=NULL) {
*byteswritten=ret;
return(TRUE);
}
-static void pipe_close_shared (gpointer handle)
+static void pipe_close (gpointer handle, gpointer data G_GNUC_UNUSED)
{
- struct _WapiHandle_file *pipe_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
- (gpointer *)&pipe_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up pipe handle %p", handle);
- return;
- }
-
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": closing pipe handle %p", handle);
+ g_message("%s: closing pipe handle %p", __func__, handle);
#endif
-
- if(pipe_handle->filename!=0) {
- _wapi_handle_scratch_delete (pipe_handle->filename);
- pipe_handle->filename=0;
- }
- if(pipe_handle->security_attributes!=0) {
- _wapi_handle_scratch_delete (pipe_handle->security_attributes);
- pipe_handle->security_attributes=0;
- }
-}
-static void pipe_close_private (gpointer handle)
-{
- struct _WapiHandlePrivate_file *pipe_private_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE, NULL,
- (gpointer *)&pipe_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up pipe handle %p", handle);
- return;
- }
-
-#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": closing pipe handle %p with fd %d", handle,
- pipe_private_handle->fd);
-#endif
-
- close(pipe_private_handle->fd);
+ /* No filename with pipe handles */
+
+ close(GPOINTER_TO_UINT(handle));
}
static WapiFileType pipe_getfiletype(void)
WapiOverlapped *overlapped G_GNUC_UNUSED)
{
struct _WapiHandle_file *pipe_handle;
- struct _WapiHandlePrivate_file *pipe_private_handle;
gboolean ok;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
- (gpointer *)&pipe_handle,
- (gpointer *)&pipe_private_handle);
+ (gpointer *)&pipe_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up pipe handle %p", handle);
+ g_warning ("%s: error looking up pipe handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
-
+
if(bytesread!=NULL) {
*bytesread=0;
}
- if(!(pipe_handle->fileaccess&GENERIC_READ) &&
- !(pipe_handle->fileaccess&GENERIC_ALL)) {
+ if(!(pipe_handle->fileaccess & GENERIC_READ) &&
+ !(pipe_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION": handle %p fd %d doesn't have GENERIC_READ access: %u", handle, pipe_private_handle->fd, pipe_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_READ access: %u",
+ __func__, handle, pipe_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": reading up to %d bytes from pipe %p (fd %d)", numbytes,
- handle, pipe_private_handle->fd);
+ g_message ("%s: reading up to %d bytes from pipe %p", __func__,
+ numbytes, handle);
#endif
do {
- ret=read(pipe_private_handle->fd, buffer, numbytes);
- }
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ ret=read(fd, buffer, numbytes);
+ } while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
- if(ret==-1) {
+ if (ret == -1) {
+ if (errno == EINTR) {
+ ret = 0;
+ } else {
+ _wapi_set_last_error_from_errno ();
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": read of handle %p fd %d error: %s", handle,
- pipe_private_handle->fd, strerror(errno));
+ g_message("%s: read of handle %p error: %s", __func__,
+ handle, strerror(errno));
#endif
- return(FALSE);
+ return(FALSE);
+ }
}
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": read %d bytes from pipe", ret);
+ g_message ("%s: read %d bytes from pipe", __func__, ret);
#endif
if(bytesread!=NULL) {
WapiOverlapped *overlapped G_GNUC_UNUSED)
{
struct _WapiHandle_file *pipe_handle;
- struct _WapiHandlePrivate_file *pipe_private_handle;
gboolean ok;
int ret;
+ int fd = GPOINTER_TO_UINT(handle);
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
- (gpointer *)&pipe_handle,
- (gpointer *)&pipe_private_handle);
+ (gpointer *)&pipe_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up pipe handle %p", handle);
+ g_warning ("%s: error looking up pipe handle %p", __func__,
+ handle);
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
*byteswritten=0;
}
- if(!(pipe_handle->fileaccess&GENERIC_WRITE) &&
- !(pipe_handle->fileaccess&GENERIC_ALL)) {
+ if(!(pipe_handle->fileaccess & GENERIC_WRITE) &&
+ !(pipe_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_WRITE access: %u", handle, pipe_private_handle->fd, pipe_handle->fileaccess);
+ g_message("%s: handle %p doesn't have GENERIC_WRITE access: %u", __func__, handle, pipe_handle->fileaccess);
#endif
+ SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
}
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": writing up to %d bytes to pipe %p (fd %d)", numbytes,
- handle, pipe_private_handle->fd);
+ g_message ("%s: writing up to %d bytes to pipe %p", __func__, numbytes,
+ handle);
#endif
- do {
- ret=write(pipe_private_handle->fd, buffer, numbytes);
- }
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ NO_SIGPIPE(
+ do {
+ ret = write (fd, buffer, numbytes);
+ } while (ret == -1 && errno == EINTR &&
+ !_wapi_thread_cur_apc_pending());
+ );
- if(ret==-1) {
+ if (ret == -1) {
+ if (errno == EINTR) {
+ ret = 0;
+ } else {
+ _wapi_set_last_error_from_errno ();
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": write of handle %p fd %d error: %s", handle,
- pipe_private_handle->fd, strerror(errno));
+ g_message("%s: write of handle %p error: %s", __func__,
+ handle, strerror(errno));
#endif
- return(FALSE);
+ return(FALSE);
+ }
}
if(byteswritten!=NULL) {
*byteswritten=ret;
break;
default:
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Unknown access type 0x%x",
+ g_message("%s: Unknown access type 0x%x", __func__,
fileaccess);
#endif
break;
break;
default:
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Unknown create mode 0x%x",
+ g_message("%s: Unknown create mode 0x%x", __func__,
createmode);
#endif
break;
fileaccess=GENERIC_READ|GENERIC_WRITE;
} else {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": Can't figure out flags 0x%x", flags);
+ g_message("%s: Can't figure out flags 0x%x", __func__, flags);
#endif
}
return(fileaccess);
}
+#if 0 /* unused */
static mode_t convert_perms(guint32 sharemode)
{
mode_t perms=0600;
return(perms);
}
+#endif
+static gboolean share_allows_open (struct stat *statbuf, guint32 sharemode,
+ guint32 fileaccess,
+ struct _WapiFileShare **share_info)
+{
+ gboolean file_already_shared;
+ guint32 file_existing_share, file_existing_access;
+
+ file_already_shared = _wapi_handle_get_or_set_share (statbuf->st_dev, statbuf->st_ino, sharemode, fileaccess, &file_existing_share, &file_existing_access, share_info);
+
+ if (file_already_shared) {
+ /* The reference to this share info was incremented
+ * when we looked it up, so be careful to put it back
+ * if we conclude we can't use this file.
+ */
+ if (file_existing_share == 0) {
+ /* Quick and easy, no possibility to share */
+#ifdef DEBUG
+ g_message ("%s: Share mode prevents open: requested access: 0x%x, file has sharing = NONE", __func__, fileaccess);
+#endif
+
+ _wapi_handle_share_release (*share_info);
+
+ return(FALSE);
+ }
+
+ if (((file_existing_share == FILE_SHARE_READ) &&
+ (fileaccess != GENERIC_READ)) ||
+ ((file_existing_share == FILE_SHARE_WRITE) &&
+ (fileaccess != GENERIC_WRITE))) {
+ /* New access mode doesn't match up */
+#ifdef DEBUG
+ g_message ("%s: Share mode prevents open: requested access: 0x%x, file has sharing: 0x%x", __func__, fileaccess, file_existing_share);
+#endif
+
+ _wapi_handle_share_release (*share_info);
+
+ return(FALSE);
+ }
+
+ if (((file_existing_access & GENERIC_READ) &&
+ !(sharemode & FILE_SHARE_READ)) ||
+ ((file_existing_access & GENERIC_WRITE) &&
+ !(sharemode & FILE_SHARE_WRITE))) {
+ /* New share mode doesn't match up */
+#ifdef DEBUG
+ g_message ("%s: Access mode prevents open: requested share: 0x%x, file has access: 0x%x", __func__, sharemode, file_existing_access);
+#endif
+
+ _wapi_handle_share_release (*share_info);
+
+ return(FALSE);
+ }
+ } else {
+#ifdef DEBUG
+ g_message ("%s: New file!", __func__);
+#endif
+ }
+
+ return(TRUE);
+}
+
+static gboolean share_check (struct stat *statbuf, guint32 sharemode,
+ guint32 fileaccess,
+ struct _WapiFileShare **share_info, int fd)
+{
+ if (share_allows_open (statbuf, sharemode, fileaccess,
+ share_info) == TRUE) {
+ return (TRUE);
+ }
+
+ /* Got a share violation. Double check that the file is still
+ * open by someone, in case a process crashed while still
+ * holding a file handle. This will also cope with someone
+ * using Mono.Posix to close the file. This is cheaper and
+ * less intrusive to other processes than initiating a handle
+ * collection.
+ */
+
+ _wapi_handle_check_share (*share_info, fd);
+ if (share_allows_open (statbuf, sharemode, fileaccess,
+ share_info) == TRUE) {
+ return (TRUE);
+ }
+
+ /* Still violating. It's possible that a process crashed
+ * while still holding a file handle, and that a non-mono
+ * process has the file open. (For example, C-c mcs while
+ * editing a source file.) As a last resort, run a handle
+ * collection, which will remove stale share entries.
+ */
+ _wapi_handle_collect ();
+
+ return(share_allows_open (statbuf, sharemode, fileaccess, share_info));
+}
/**
* CreateFile:
guint32 createmode, guint32 attrs,
gpointer template G_GNUC_UNUSED)
{
- struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
+ struct _WapiHandle_file file_handle = {0};
gpointer handle;
- gboolean ok;
int flags=convert_flags(fileaccess, createmode);
- mode_t perms=convert_perms(sharemode);
+ /*mode_t perms=convert_perms(sharemode);*/
+ /* we don't use sharemode, because that relates to sharing of
+ * the file when the file is open and is already handled by
+ * other code, perms instead are the on-disk permissions and
+ * this is a sane default.
+ */
+ mode_t perms=0644;
gchar *filename;
int fd, ret;
- int thr_ret;
- gpointer cf_ret = INVALID_HANDLE_VALUE;
struct stat statbuf;
- gboolean file_already_shared;
- guint32 file_existing_share, file_existing_access;
mono_once (&io_ops_once, io_ops_init);
- if(name==NULL) {
+ if (name == NULL) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+ g_message ("%s: name is NULL", __func__);
#endif
+ SetLastError (ERROR_INVALID_NAME);
return(INVALID_HANDLE_VALUE);
}
- filename=mono_unicode_to_external (name);
- if(filename==NULL) {
+ filename = mono_unicode_to_external (name);
+ if (filename == NULL) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": unicode conversion returned NULL");
+ g_message("%s: unicode conversion returned NULL", __func__);
#endif
+ SetLastError (ERROR_INVALID_NAME);
return(INVALID_HANDLE_VALUE);
}
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Opening %s with share 0x%x and access 0x%x", filename, sharemode, fileaccess);
+ g_message ("%s: Opening %s with share 0x%x and access 0x%x", __func__,
+ filename, sharemode, fileaccess);
#endif
fd = open(filename, flags, perms);
if (fd == -1) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Error opening file %s: %s",
- filename, strerror(errno));
+ g_message("%s: Error opening file %s: %s", __func__, filename,
+ strerror(errno));
#endif
_wapi_set_last_error_from_errno ();
g_free (filename);
return(INVALID_HANDLE_VALUE);
}
+ if (fd >= _wapi_fd_reserve) {
+#ifdef DEBUG
+ g_message ("%s: File descriptor is too big", __func__);
+#endif
+
+ SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+
+ close (fd);
+ g_free (filename);
+
+ return(INVALID_HANDLE_VALUE);
+ }
+
ret = fstat (fd, &statbuf);
if (ret == -1) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": fstat error of file %s: %s", filename, strerror (errno));
+ g_message ("%s: fstat error of file %s: %s", __func__,
+ filename, strerror (errno));
#endif
_wapi_set_last_error_from_errno ();
g_free (filename);
return(INVALID_HANDLE_VALUE);
}
- file_already_shared = _wapi_handle_get_or_set_share (statbuf.st_dev, statbuf.st_ino, sharemode, fileaccess, &file_existing_share, &file_existing_access);
-
- if (file_already_shared) {
- if (file_existing_share == 0) {
- /* Quick and easy, no possibility to share */
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Share mode prevents open: requested access: 0x%x, file has sharing = NONE", fileaccess);
-#endif
- SetLastError (ERROR_SHARING_VIOLATION);
- g_free (filename);
- close (fd);
+ if (share_check (&statbuf, sharemode, fileaccess,
+ &file_handle.share_info, fd) == FALSE) {
+ SetLastError (ERROR_SHARING_VIOLATION);
+ g_free (filename);
+ close (fd);
- return(INVALID_HANDLE_VALUE);
- }
-
- if (((file_existing_share == FILE_SHARE_READ) &&
- (fileaccess != GENERIC_READ)) ||
- ((file_existing_share == FILE_SHARE_WRITE) &&
- (fileaccess != GENERIC_WRITE))) {
- /* New access mode doesn't match up */
+ return (INVALID_HANDLE_VALUE);
+ }
+ if (file_handle.share_info == NULL) {
+ /* No space, so no more files can be opened */
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Share mode prevents open: requested access: 0x%x, file has sharing: 0x%x", fileaccess, file_existing_share);
+ g_message ("%s: No space in the share table", __func__);
#endif
- SetLastError (ERROR_SHARING_VIOLATION);
- g_free (filename);
- close (fd);
-
- return(INVALID_HANDLE_VALUE);
- }
- if (((file_existing_access & GENERIC_READ) &&
- !(sharemode & FILE_SHARE_READ)) ||
- ((file_existing_access & GENERIC_WRITE) &&
- !(sharemode & FILE_SHARE_WRITE))) {
- /* New share mode doesn't match up */
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Access mode prevents open: requested share: 0x%x, file has access: 0x%x", sharemode, file_existing_access);
-#endif
- SetLastError (ERROR_SHARING_VIOLATION);
- g_free (filename);
- close (fd);
-
- return(INVALID_HANDLE_VALUE);
- }
- } else {
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": New file!");
-#endif
- }
-
- handle=_wapi_handle_new (WAPI_HANDLE_FILE);
- if(handle==_WAPI_HANDLE_INVALID) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error creating file handle");
- g_free (filename);
+ SetLastError (ERROR_TOO_MANY_OPEN_FILES);
close (fd);
+ g_free (filename);
return(INVALID_HANDLE_VALUE);
}
-
- pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
- handle);
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
- close (fd);
- goto cleanup;
- }
- cf_ret = handle;
+ file_handle.filename = filename;
- file_private_handle->fd=fd;
- file_private_handle->assigned=TRUE;
- file_private_handle->async = ((attrs & FILE_FLAG_OVERLAPPED) != 0);
- file_handle->filename=_wapi_handle_scratch_store (filename,
- strlen (filename));
if(security!=NULL) {
- file_handle->security_attributes=_wapi_handle_scratch_store (
- security, sizeof(WapiSecurityAttributes));
+ //file_handle->security_attributes=_wapi_handle_scratch_store (
+ //security, sizeof(WapiSecurityAttributes));
}
- file_handle->fileaccess=fileaccess;
- file_handle->sharemode=sharemode;
- file_handle->attrs=attrs;
- file_handle->device = statbuf.st_dev;
- file_handle->inode = statbuf.st_ino;
+ file_handle.fileaccess=fileaccess;
+ file_handle.sharemode=sharemode;
+ file_handle.attrs=attrs;
+
+ handle = _wapi_handle_new_fd (WAPI_HANDLE_FILE, fd, &file_handle);
+ if (handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating file handle", __func__);
+ g_free (filename);
+ close (fd);
+
+ SetLastError (ERROR_GEN_FAILURE);
+ return(INVALID_HANDLE_VALUE);
+ }
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": returning handle %p with fd %d", handle,
- file_private_handle->fd);
+ g_message("%s: returning handle %p", __func__, handle);
#endif
-
-cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
-
- g_free (filename);
- return(cf_ret);
+ return(handle);
}
/**
if(name==NULL) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": name is NULL");
+ g_message("%s: name is NULL", __func__);
#endif
+ SetLastError (ERROR_INVALID_NAME);
return(FALSE);
}
filename=mono_unicode_to_external(name);
if(filename==NULL) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": unicode conversion returned NULL");
+ g_message("%s: unicode conversion returned NULL", __func__);
#endif
+ SetLastError (ERROR_INVALID_NAME);
return(FALSE);
}
* @dest_name: a pointer to a NULL-terminated unicode string, that is the
* new name for the file.
*
- * Renames file @name to @dest_name
+ * Renames file @name to @dest_name.
+ * MoveFile sets ERROR_ALREADY_EXISTS if the destination exists, except
+ * when it is the same file as the source. In that case it silently succeeds.
*
* Return value: %TRUE on success, %FALSE otherwise.
*/
{
gchar *utf8_name, *utf8_dest_name;
int result;
+ struct stat stat_src, stat_dest;
+
+ if(name==NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
+ g_message ("%s: unicode conversion returned NULL", __func__);
#endif
+ SetLastError (ERROR_INVALID_NAME);
return FALSE;
}
+
+ if(dest_name==NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ g_free (utf8_name);
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_dest_name = mono_unicode_to_external (dest_name);
if (utf8_dest_name == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
+ g_message ("%s: unicode conversion returned NULL", __func__);
#endif
g_free (utf8_name);
+ SetLastError (ERROR_INVALID_NAME);
return FALSE;
}
+ /*
+ * In C# land we check for the existence of src, but not for dest.
+ * We check it here and return the failure if dest exists and is not
+ * the same file as src.
+ */
+ if (!stat (utf8_dest_name, &stat_dest) && !stat (utf8_name, &stat_src)) {
+ if (stat_dest.st_dev != stat_src.st_dev || stat_dest.st_ino != stat_src.st_ino) {
+ SetLastError (ERROR_ALREADY_EXISTS);
+ return FALSE;
+ }
+ }
+
result = rename (utf8_name, utf8_dest_name);
g_free (utf8_name);
g_free (utf8_dest_name);
if (result != 0 && errno == EXDEV) {
/* Try a copy to the new location, and delete the source */
if (CopyFile (name, dest_name, TRUE)==FALSE) {
+ /* CopyFile will set the error */
return(FALSE);
}
int remain, n;
struct stat st;
+ if(name==NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
+
utf8_src = mono_unicode_to_external (name);
if (utf8_src == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion of source returned NULL");
+ g_message ("%s: unicode conversion of source returned NULL",
+ __func__);
#endif
SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
+ if(dest_name==NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ g_free (utf8_src);
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
+
utf8_dest = mono_unicode_to_external (dest_name);
if (utf8_dest == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion of dest returned NULL");
+ g_message ("%s: unicode conversion of dest returned NULL",
+ __func__);
#endif
SetLastError (ERROR_INVALID_PARAMETER);
_wapi_set_last_error_from_errno ();
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": write failed.");
+ g_message ("%s: write failed.", __func__);
#endif
g_free (utf8_src);
}
static mono_once_t stdhandle_once=MONO_ONCE_INIT;
-static gpointer stdin_handle=NULL;
-static gpointer stdout_handle=NULL;
-static gpointer stderr_handle=NULL;
+static gpointer stdin_handle=INVALID_HANDLE_VALUE;
+static gpointer stdout_handle=INVALID_HANDLE_VALUE;
+static gpointer stderr_handle=INVALID_HANDLE_VALUE;
static gpointer stdhandle_create (int fd, const guchar *name)
{
- struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
- gboolean ok;
- gpointer handle, ret = NULL;
+ struct _WapiHandle_file file_handle = {0};
+ gpointer handle;
int flags;
- int thr_ret;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": creating standard handle type %s",
- name);
+ g_message("%s: creating standard handle type %s, fd %d", __func__,
+ name, fd);
#endif
/* Check if fd is valid */
do {
flags=fcntl(fd, F_GETFL);
- }
- while (flags==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ } while (flags == -1 && errno == EINTR);
if(flags==-1) {
/* Invalid fd. Not really much point checking for EBADF
* specifically
*/
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": fcntl error on fd %d: %s",
- fd, strerror(errno));
+ g_message("%s: fcntl error on fd %d: %s", __func__, fd,
+ strerror(errno));
#endif
+ _wapi_set_last_error_from_errno ();
return(INVALID_HANDLE_VALUE);
}
- handle=_wapi_handle_new (WAPI_HANDLE_CONSOLE);
- if(handle==_WAPI_HANDLE_INVALID) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error creating file handle");
- return(NULL);
- }
-
- pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
- handle);
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up console handle %p", handle);
- goto cleanup;
- }
- ret = handle;
-
- file_private_handle->fd=fd;
- file_private_handle->assigned=TRUE;
- file_handle->filename=_wapi_handle_scratch_store (name, strlen (name));
+ file_handle.filename = g_strdup(name);
/* some default security attributes might be needed */
- file_handle->security_attributes=0;
- file_handle->fileaccess=convert_from_flags(flags);
- file_handle->sharemode=0;
- file_handle->attrs=0;
+ file_handle.security_attributes=0;
+ file_handle.fileaccess=convert_from_flags(flags);
+ file_handle.sharemode=0;
+ file_handle.attrs=0;
+
+ handle = _wapi_handle_new_fd (WAPI_HANDLE_CONSOLE, fd, &file_handle);
+ if (handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating file handle", __func__);
+ SetLastError (ERROR_GEN_FAILURE);
+ return(INVALID_HANDLE_VALUE);
+ }
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": returning handle %p with fd %d",
- handle, file_private_handle->fd);
+ g_message("%s: returning handle %p", __func__, handle);
#endif
-cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
-
- return(ret);
+ return(handle);
}
static void stdhandle_init (void)
default:
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": unknown standard handle type");
+ g_message("%s: unknown standard handle type", __func__);
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(INVALID_HANDLE_VALUE);
}
+ if (handle == INVALID_HANDLE_VALUE) {
+ SetLastError (ERROR_NO_MORE_FILES);
+ return(INVALID_HANDLE_VALUE);
+ }
+
/* Add a reference to this handle */
_wapi_handle_ref (handle);
gboolean ReadFile(gpointer handle, gpointer buffer, guint32 numbytes,
guint32 *bytesread, WapiOverlapped *overlapped)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].readfile==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
gboolean WriteFile(gpointer handle, gconstpointer buffer, guint32 numbytes,
guint32 *byteswritten, WapiOverlapped *overlapped)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].writefile==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
*/
gboolean FlushFileBuffers(gpointer handle)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ type = _wapi_handle_type (handle);
if(io_ops[type].flushfile==NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
*/
gboolean SetEndOfFile(gpointer handle)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ type = _wapi_handle_type (handle);
- if(io_ops[type].setendoffile==NULL) {
+ if (io_ops[type].setendoffile == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
guint32 SetFilePointer(gpointer handle, gint32 movedistance,
gint32 *highmovedistance, WapiSeekMethod method)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ type = _wapi_handle_type (handle);
- if(io_ops[type].seek==NULL) {
- return(FALSE);
+ if (io_ops[type].seek == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(INVALID_SET_FILE_POINTER);
}
return(io_ops[type].seek (handle, movedistance, highmovedistance,
*/
WapiFileType GetFileType(gpointer handle)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ if (!_WAPI_PRIVATE_HAVE_SLOT (handle)) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FILE_TYPE_UNKNOWN);
+ }
+
+ type = _wapi_handle_type (handle);
- if(io_ops[type].getfiletype==NULL) {
+ if (io_ops[type].getfiletype == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FILE_TYPE_UNKNOWN);
}
*/
guint32 GetFileSize(gpointer handle, guint32 *highsize)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ type = _wapi_handle_type (handle);
- if(io_ops[type].getfilesize==NULL) {
- return(FALSE);
+ if (io_ops[type].getfilesize == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(INVALID_FILE_SIZE);
}
return(io_ops[type].getfilesize (handle, highsize));
gboolean GetFileTime(gpointer handle, WapiFileTime *create_time,
WapiFileTime *last_access, WapiFileTime *last_write)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ type = _wapi_handle_type (handle);
- if(io_ops[type].getfiletime==NULL) {
+ if (io_ops[type].getfiletime == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
const WapiFileTime *last_access,
const WapiFileTime *last_write)
{
- WapiHandleType type=_wapi_handle_type (handle);
+ WapiHandleType type;
+
+ type = _wapi_handle_type (handle);
- if(io_ops[type].setfiletime==NULL) {
+ if (io_ops[type].setfiletime == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
if(system_time==NULL) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": system_time NULL");
+ g_message("%s: system_time NULL", __func__);
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
*/
if(file_ticks<0) {
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": file_time too big");
+ g_message("%s: file_time too big", __func__);
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
totaldays=(file_ticks / TICKS_PER_DAY);
rem = file_ticks % TICKS_PER_DAY;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": totaldays: %lld rem: %lld",
- totaldays, rem);
+ g_message("%s: totaldays: %lld rem: %lld", __func__, totaldays, rem);
#endif
system_time->wHour=rem/TICKS_PER_HOUR;
rem %= TICKS_PER_HOUR;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Hour: %d rem: %lld",
- system_time->wHour, rem);
+ g_message("%s: Hour: %d rem: %lld", __func__, system_time->wHour, rem);
#endif
system_time->wMinute = rem / TICKS_PER_MINUTE;
rem %= TICKS_PER_MINUTE;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Minute: %d rem: %lld",
- system_time->wMinute, rem);
+ g_message("%s: Minute: %d rem: %lld", __func__, system_time->wMinute,
+ rem);
#endif
system_time->wSecond = rem / TICKS_PER_SECOND;
rem %= TICKS_PER_SECOND;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Second: %d rem: %lld",
- system_time->wSecond, rem);
+ g_message("%s: Second: %d rem: %lld", __func__, system_time->wSecond,
+ rem);
#endif
system_time->wMilliseconds = rem / TICKS_PER_MILLISECOND;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Milliseconds: %d",
+ g_message("%s: Milliseconds: %d", __func__,
system_time->wMilliseconds);
#endif
/* January 1, 1601 was a Monday, according to Emacs calendar */
system_time->wDayOfWeek = ((1 + totaldays) % 7) + 1;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Day of week: %d",
- system_time->wDayOfWeek);
+ g_message("%s: Day of week: %d", __func__, system_time->wDayOfWeek);
#endif
/* This algorithm to find year and month given days from epoch
/* Guess a corrected year, assuming 365 days per year */
gint64 yg = y + totaldays / 365 - (totaldays % 365 < 0);
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": totaldays: %lld yg: %lld y: %lld", totaldays, yg,
+ g_message("%s: totaldays: %lld yg: %lld y: %lld", __func__,
+ totaldays, yg,
y);
- g_message(G_GNUC_PRETTY_FUNCTION
- ": LEAPS(yg): %lld LEAPS(y): %lld",
+ g_message("%s: LEAPS(yg): %lld LEAPS(y): %lld", __func__,
LEAPS_THRU_END_OF(yg-1), LEAPS_THRU_END_OF(y-1));
#endif
+ LEAPS_THRU_END_OF (yg - 1)
- LEAPS_THRU_END_OF (y - 1));
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": totaldays: %lld",
- totaldays);
+ g_message("%s: totaldays: %lld", __func__, totaldays);
#endif
y = yg;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": y: %lld", y);
+ g_message("%s: y: %lld", __func__, y);
#endif
}
system_time->wYear = y;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Year: %d", system_time->wYear);
+ g_message("%s: Year: %d", __func__, system_time->wYear);
#endif
ip = mon_yday[isleap(y)];
}
totaldays-=ip[y];
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": totaldays: %lld", totaldays);
+ g_message("%s: totaldays: %lld", __func__, totaldays);
#endif
system_time->wMonth = y + 1;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Month: %d", system_time->wMonth);
+ g_message("%s: Month: %d", __func__, system_time->wMonth);
#endif
system_time->wDay = totaldays + 1;
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Day: %d", system_time->wDay);
+ g_message("%s: Day: %d", __func__, system_time->wDay);
#endif
return(TRUE);
gpointer FindFirstFile (const gunichar2 *pattern, WapiFindData *find_data)
{
- struct _WapiHandlePrivate_find *find_handle;
- gpointer handle, find_ret = INVALID_HANDLE_VALUE;
- gboolean ok;
+ struct _WapiHandle_find find_handle = {0};
+ gpointer handle;
gchar *utf8_pattern = NULL, *dir_part, *entry_part;
int result;
- int thr_ret;
- gboolean unref = FALSE;
if (pattern == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": pattern is NULL");
+ g_message ("%s: pattern is NULL", __func__);
#endif
SetLastError (ERROR_PATH_NOT_FOUND);
utf8_pattern = mono_unicode_to_external (pattern);
if (utf8_pattern == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
+ g_message ("%s: unicode conversion returned NULL", __func__);
#endif
SetLastError (ERROR_INVALID_NAME);
}
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": looking for [%s]",
- utf8_pattern);
+ g_message ("%s: looking for [%s]", __func__, utf8_pattern);
#endif
/* Figure out which bit of the pattern is the directory */
- dir_part=g_path_get_dirname (utf8_pattern);
- entry_part=g_path_get_basename (utf8_pattern);
+ dir_part = g_path_get_dirname (utf8_pattern);
+ entry_part = g_path_get_basename (utf8_pattern);
#if 0
/* Don't do this check for now, it breaks if directories
return(INVALID_HANDLE_VALUE);
}
#endif
-
- handle=_wapi_handle_new (WAPI_HANDLE_FIND);
- if(handle==_WAPI_HANDLE_INVALID) {
- g_warning (G_GNUC_PRETTY_FUNCTION ": error creating find handle");
- g_free (dir_part);
- g_free (entry_part);
- g_free (utf8_pattern);
-
- return(INVALID_HANDLE_VALUE);
- }
-
- pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
- handle);
- thr_ret = _wapi_handle_lock_handle (handle);
- g_assert (thr_ret == 0);
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND, NULL,
- (gpointer *)&find_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up find handle %p", handle);
- g_free (dir_part);
- dir_part = NULL;
- g_free (entry_part);
- entry_part = NULL;
- g_free (utf8_pattern);
- utf8_pattern = NULL;
- goto cleanup;
- }
/* The pattern can specify a directory or a set of files.
*
* than mess around with regexes.
*/
- find_handle->namelist = NULL;
- result = mono_io_scandir (dir_part, entry_part, &find_handle->namelist);
+ find_handle.namelist = NULL;
+ result = mono_io_scandir (dir_part, entry_part, &find_handle.namelist);
if (result < 0) {
#ifdef DEBUG
#endif
_wapi_set_last_error_from_errno ();
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": scandir error: %s", g_strerror (errnum));
+ g_message ("%s: scandir error: %s", __func__,
+ g_strerror (errnum));
#endif
g_free (utf8_pattern);
g_free (entry_part);
g_free (dir_part);
- unref = TRUE;
- goto cleanup;
+ return (INVALID_HANDLE_VALUE);
}
g_free (utf8_pattern);
g_free (entry_part);
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Got %d matches", result);
+ g_message ("%s: Got %d matches", __func__, result);
#endif
- find_handle->dir_part = dir_part;
- find_handle->num = result;
- find_handle->count = 0;
-
- find_ret = handle;
-
-cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
+ find_handle.dir_part = dir_part;
+ find_handle.num = result;
+ find_handle.count = 0;
+
+ handle = _wapi_handle_new (WAPI_HANDLE_FIND, &find_handle);
+ if (handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating find handle", __func__);
+ g_free (dir_part);
+ g_free (entry_part);
+ g_free (utf8_pattern);
+ SetLastError (ERROR_GEN_FAILURE);
+
+ return(INVALID_HANDLE_VALUE);
+ }
- /* FindNextFile has to be called after unlocking the handle,
- * because it wants to lock the handle itself
- */
- if (find_ret != INVALID_HANDLE_VALUE &&
+ if (handle != INVALID_HANDLE_VALUE &&
!FindNextFile (handle, find_data)) {
FindClose (handle);
SetLastError (ERROR_NO_MORE_FILES);
- find_ret = INVALID_HANDLE_VALUE;
+ handle = INVALID_HANDLE_VALUE;
}
- /* Must not call _wapi_handle_unref() with the handle already
- * locked
- */
- if (unref) {
- _wapi_handle_unref (handle);
- }
-
- return (find_ret);
+ return (handle);
}
gboolean FindNextFile (gpointer handle, WapiFindData *find_data)
{
- struct _WapiHandlePrivate_find *find_handle;
+ struct _WapiHandle_find *find_handle;
gboolean ok;
struct stat buf;
gchar *filename;
int thr_ret;
gboolean ret = FALSE;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND, NULL,
+ ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND,
(gpointer *)&find_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up find handle %p", handle);
+ g_warning ("%s: error looking up find handle %p", __func__,
+ handle);
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
filename = g_build_filename (find_handle->dir_part, find_handle->namelist[find_handle->count ++], NULL);
if (lstat (filename, &buf) != 0) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": stat failed: %s", filename);
+ g_message ("%s: stat failed: %s", __func__, filename);
#endif
g_free (filename);
}
}
- utf8_filename=mono_utf8_from_external (filename);
- if(utf8_filename==NULL) {
+ utf8_filename = mono_utf8_from_external (filename);
+ if (utf8_filename == NULL) {
/* We couldn't turn this filename into utf8 (eg the
* encoding of the name wasn't convertible), so just
* ignore it.
g_free (filename);
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Found [%s]", utf8_filename);
+ g_message ("%s: Found [%s]", __func__, utf8_filename);
#endif
/* fill data block */
if (find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
find_data->nFileSizeHigh = 0;
find_data->nFileSizeLow = 0;
- }
- else {
+ } else {
find_data->nFileSizeHigh = buf.st_size >> 32;
find_data->nFileSizeLow = buf.st_size & 0xFFFFFFFF;
}
*/
gboolean FindClose (gpointer handle)
{
- struct _WapiHandlePrivate_find *find_handle;
+ struct _WapiHandle_find *find_handle;
gboolean ok;
int thr_ret;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND, NULL,
+ ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FIND,
(gpointer *)&find_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up find handle %p", handle);
+ g_warning ("%s: error looking up find handle %p", __func__,
+ handle);
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
*
* Return value: %TRUE on success, %FALSE otherwise.
*/
-gboolean CreateDirectory (const gunichar2 *name, WapiSecurityAttributes *security)
+gboolean CreateDirectory (const gunichar2 *name,
+ WapiSecurityAttributes *security)
{
gchar *utf8_name;
int result;
struct stat buf;
guint32 attrs;
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
+
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
+ g_message ("%s: unicode conversion returned NULL", __func__);
#endif
+ SetLastError (ERROR_INVALID_NAME);
return FALSE;
}
{
gchar *utf8_name;
int result;
+
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
+ g_message ("%s: unicode conversion returned NULL", __func__);
#endif
+ SetLastError (ERROR_INVALID_NAME);
return FALSE;
}
struct stat buf;
int result;
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
+
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
+ g_message ("%s: unicode conversion returned NULL", __func__);
#endif
SetLastError (ERROR_INVALID_PARAMETER);
if (level != GetFileExInfoStandard) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": info level %d not supported.", level);
+ g_message ("%s: info level %d not supported.", __func__,
+ level);
#endif
+ SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
+
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_name = mono_unicode_to_external (name);
if (utf8_name == NULL) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": unicode conversion returned NULL");
+ g_message ("%s: unicode conversion returned NULL", __func__);
#endif
SetLastError (ERROR_INVALID_PARAMETER);
* Currently we only handle one *internal* case, with a value that is
* not standard: 0x80000000, which means `set executable bit'
*/
+
+ if (name == NULL) {
+#ifdef DEBUG
+ g_message("%s: name is NULL", __func__);
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return(FALSE);
+ }
utf8_name = mono_unicode_to_external (name);
+ if (utf8_name == NULL) {
+#ifdef DEBUG
+ g_message ("%s: unicode conversion returned NULL", __func__);
+#endif
+
+ SetLastError (ERROR_INVALID_NAME);
+ return FALSE;
+ }
+
result = stat (utf8_name, &buf);
if (result != 0) {
g_free (utf8_name);
SetLastError (ERROR_FILE_NOT_FOUND);
return FALSE;
}
-
+
/* Contrary to the documentation, ms allows NORMAL to be
* specified along with other attributes, so dont bother to
* catch that case here.
return result;
}
-int _wapi_file_handle_to_fd (gpointer handle)
-{
- struct _WapiHandlePrivate_file *file_private_handle;
- gboolean ok;
-
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": looking up fd for %p", handle);
-#endif
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_CONSOLE, NULL,
- (gpointer *)&file_private_handle);
- if(ok==FALSE) {
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_FILE, NULL,
- (gpointer *)&file_private_handle);
- if(ok==FALSE) {
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PIPE, NULL,
- (gpointer *)&file_private_handle);
- if(ok==FALSE) {
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": returning -1");
-#endif
- return(-1);
- }
- }
- }
-
-#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": returning %d",
- file_private_handle->fd);
-#endif
-
- return(file_private_handle->fd);
-}
-
gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
WapiSecurityAttributes *security G_GNUC_UNUSED, guint32 size)
{
- struct _WapiHandle_file *pipe_read_handle;
- struct _WapiHandle_file *pipe_write_handle;
- struct _WapiHandlePrivate_file *pipe_read_private_handle;
- struct _WapiHandlePrivate_file *pipe_write_private_handle;
+ struct _WapiHandle_file pipe_read_handle = {0};
+ struct _WapiHandle_file pipe_write_handle = {0};
gpointer read_handle;
gpointer write_handle;
- gboolean ok;
int filedes[2];
int ret;
- int thr_ret;
- gboolean unref_read = FALSE, unref_write = FALSE;
- gboolean cp_ret = FALSE;
mono_once (&io_ops_once, io_ops_init);
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Creating pipe");
+ g_message ("%s: Creating pipe", __func__);
#endif
ret=pipe (filedes);
if(ret==-1) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": Error creating pipe: %s",
+ g_message ("%s: Error creating pipe: %s", __func__,
strerror (errno));
#endif
_wapi_set_last_error_from_errno ();
return(FALSE);
}
-
- /* filedes[0] is open for reading, filedes[1] for writing */
- read_handle=_wapi_handle_new (WAPI_HANDLE_PIPE);
- if(read_handle==_WAPI_HANDLE_INVALID) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error creating pipe read handle");
+ if (filedes[0] >= _wapi_fd_reserve ||
+ filedes[1] >= _wapi_fd_reserve) {
+#ifdef DEBUG
+ g_message ("%s: File descriptor is too big", __func__);
+#endif
+
+ SetLastError (ERROR_TOO_MANY_OPEN_FILES);
+
close (filedes[0]);
close (filedes[1]);
+
return(FALSE);
}
- pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
- read_handle);
- thr_ret = _wapi_handle_lock_handle (read_handle);
- g_assert (thr_ret == 0);
+ /* filedes[0] is open for reading, filedes[1] for writing */
- ok=_wapi_lookup_handle (read_handle, WAPI_HANDLE_PIPE,
- (gpointer *)&pipe_read_handle,
- (gpointer *)&pipe_read_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION ": error looking up pipe handle %p", read_handle);
+ pipe_read_handle.fileaccess = GENERIC_READ;
+ read_handle = _wapi_handle_new_fd (WAPI_HANDLE_PIPE, filedes[0],
+ &pipe_read_handle);
+ if (read_handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating pipe read handle", __func__);
close (filedes[0]);
close (filedes[1]);
- goto cleanup;
- }
-
- write_handle=_wapi_handle_new (WAPI_HANDLE_PIPE);
- if(write_handle==_WAPI_HANDLE_INVALID) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error creating pipe write handle");
- unref_read = TRUE;
+ SetLastError (ERROR_GEN_FAILURE);
- close (filedes[0]);
- close (filedes[1]);
- goto cleanup;
+ return(FALSE);
}
- pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
- write_handle);
- thr_ret = _wapi_handle_lock_handle (write_handle);
- g_assert (thr_ret == 0);
-
- ok=_wapi_lookup_handle (write_handle, WAPI_HANDLE_PIPE,
- (gpointer *)&pipe_write_handle,
- (gpointer *)&pipe_write_private_handle);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION ": error looking up pipe handle %p", read_handle);
- unref_read = TRUE;
- unref_write = TRUE;
+ pipe_write_handle.fileaccess = GENERIC_WRITE;
+ write_handle = _wapi_handle_new_fd (WAPI_HANDLE_PIPE, filedes[1],
+ &pipe_write_handle);
+ if (write_handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating pipe write handle", __func__);
+ _wapi_handle_unref (read_handle);
close (filedes[0]);
close (filedes[1]);
- goto write_cleanup;
+ SetLastError (ERROR_GEN_FAILURE);
+
+ return(FALSE);
}
- cp_ret = TRUE;
-
- pipe_read_private_handle->fd=filedes[0];
- pipe_read_private_handle->assigned=TRUE;
- pipe_read_handle->fileaccess=GENERIC_READ;
-
- *readpipe=read_handle;
-
- pipe_write_private_handle->fd=filedes[1];
- pipe_write_private_handle->assigned=TRUE;
- pipe_write_handle->fileaccess=GENERIC_WRITE;
- *writepipe=write_handle;
+ *readpipe = read_handle;
+ *writepipe = write_handle;
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": Returning pipe: read handle %p, write handle %p",
- read_handle, write_handle);
+ g_message ("%s: Returning pipe: read handle %p, write handle %p",
+ __func__, read_handle, write_handle);
#endif
-write_cleanup:
- thr_ret =_wapi_handle_unlock_handle (write_handle);
- g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
-
- if (unref_write) {
- _wapi_handle_unref (write_handle);
- }
-
-cleanup:
- thr_ret =_wapi_handle_unlock_handle (read_handle);
- g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
-
- /* Must not call _wapi_handle_unref() with the handle already
- * locked
- */
- if (unref_read) {
- _wapi_handle_unref (read_handle);
- }
-
- return(cp_ret);
+ return(TRUE);
}
guint32 GetTempPath (guint32 len, gunichar2 *buf)
if(dirlen+1>len) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": Size %d smaller than needed (%ld)", len,
- dirlen+1);
+ g_message ("%s: Size %d smaller than needed (%ld)",
+ __func__, len, dirlen+1);
#endif
ret=dirlen+1;
return(ret);
}
-gboolean
-_wapi_io_add_callback (gpointer handle,
- WapiOverlappedCB callback,
- guint64 flags G_GNUC_UNUSED)
-{
- struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
- gboolean ok;
- int thr_ret;
- gboolean ret = FALSE;
-
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *) &file_handle,
- (gpointer *) &file_private_handle);
-
- if (ok == FALSE) {
- ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PIPE,
- (gpointer *) &file_handle,
- (gpointer *) &file_private_handle);
-
- }
-
- if (ok == FALSE || file_private_handle->async == FALSE) {
- SetLastError (ERROR_INVALID_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);
-
- if (file_private_handle->callback != NULL) {
- SetLastError (ERROR_INVALID_PARAMETER);
- goto cleanup;
- }
- ret = TRUE;
-
- file_private_handle->callback = callback;
-
-cleanup:
- thr_ret = _wapi_handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
-
- return(ret);
-}
-
gint32
GetLogicalDriveStrings (guint32 len, gunichar2 *buf)
{
continue;
splitted = g_strsplit (buffer, " ", 0);
- if (!*splitted || !*(splitted + 1))
+ if (!*splitted || !*(splitted + 1)) {
+ g_strfreev (splitted);
continue;
+ }
dir = g_utf8_to_utf16 (*(splitted + 1), -1, &length, NULL, NULL);
g_strfreev (splitted);
if (total + length + 1 > len) {
+ fclose (fp);
return len * 2; /* guess */
}
do {
ret = fcntl (fd, F_SETLK, &lock_data);
- }
- while(ret == -1 && errno == EINTR && !_wapi_thread_cur_apc_pending ());
+ } while(ret == -1 && errno == EINTR);
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": fcntl returns %d", ret);
+ g_message ("%s: fcntl returns %d", __func__, ret);
#endif
if (ret == -1) {
+ /*
+ * if locks are not available (NFS for example),
+ * ignore the error
+ */
+ if (errno == ENOLCK
+#ifdef EOPNOTSUPP
+ || errno == EOPNOTSUPP
+#endif
+#ifdef ENOTSUP
+ || errno == ENOTSUP
+#endif
+ ) {
+ return (TRUE);
+ }
+
SetLastError (ERROR_LOCK_VIOLATION);
return(FALSE);
}
do {
ret = fcntl (fd, F_SETLK, &lock_data);
- }
- while(ret == -1 && errno == EINTR && !_wapi_thread_cur_apc_pending ());
+ } while(ret == -1 && errno == EINTR);
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": fcntl returns %d", ret);
+ g_message ("%s: fcntl returns %d", __func__, ret);
#endif
if (ret == -1) {
+ /*
+ * if locks are not available (NFS for example),
+ * ignore the error
+ */
+ if (errno == ENOLCK
+#ifdef EOPNOTSUPP
+ || errno == EOPNOTSUPP
+#endif
+#ifdef ENOTSUP
+ || errno == ENOTSUP
+#endif
+ ) {
+ return (TRUE);
+ }
+
SetLastError (ERROR_LOCK_VIOLATION);
return(FALSE);
}
guint32 length_low, guint32 length_high)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
off_t offset, length;
+ int fd = GPOINTER_TO_UINT(handle);
ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if (ok == FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
!(file_handle->fileaccess & GENERIC_WRITE) &&
!(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message ("%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
length = ((gint64)length_high << 32) | length_low;
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": Locking handle %p fd %d, offset %lld, length %lld",
- handle, file_private_handle->fd, offset, length);
+ g_message ("%s: Locking handle %p, offset %lld, length %lld", __func__,
+ handle, offset, length);
#endif
#else
offset = offset_low;
length = length_low;
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": Locking handle %p fd %d, offset %ld, length %ld",
- handle, file_private_handle->fd, offset, length);
+ g_message ("%s: Locking handle %p, offset %ld, length %ld", __func__,
+ handle, offset, length);
#endif
#endif
- return(_wapi_lock_file_region (file_private_handle->fd, offset,
- length));
+ return(_wapi_lock_file_region (fd, offset, length));
}
-gboolean UnlockFile (gpointer handle, guint32 offset_low, guint32 offset_high,
- guint32 length_low, guint32 length_high)
+gboolean UnlockFile (gpointer handle, guint32 offset_low,
+ guint32 offset_high, guint32 length_low,
+ guint32 length_high)
{
struct _WapiHandle_file *file_handle;
- struct _WapiHandlePrivate_file *file_private_handle;
gboolean ok;
off_t offset, length;
+ int fd = GPOINTER_TO_UINT(handle);
ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
- (gpointer *)&file_handle,
- (gpointer *)&file_private_handle);
+ (gpointer *)&file_handle);
if (ok == FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up file handle %p", handle);
+ g_warning ("%s: error looking up file handle %p", __func__,
+ handle);
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
-
+
if (!(file_handle->fileaccess & GENERIC_READ) &&
!(file_handle->fileaccess & GENERIC_WRITE) &&
!(file_handle->fileaccess & GENERIC_ALL)) {
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": handle %p fd %d doesn't have GENERIC_READ or GENERIC_WRITE access: %u", handle, file_private_handle->fd, file_handle->fileaccess);
+ g_message ("%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
#endif
SetLastError (ERROR_ACCESS_DENIED);
return(FALSE);
length = ((gint64)length_high << 32) | length_low;
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": Unlocking handle %p fd %d, offset %lld, length %lld",
- handle, file_private_handle->fd, offset, length);
+ g_message ("%s: Unlocking handle %p, offset %lld, length %lld",
+ __func__, handle, offset, length);
#endif
#else
offset = offset_low;
length = length_low;
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION
- ": Unlocking handle %p fd %d, offset %ld, length %ld",
- handle, file_private_handle->fd, offset, length);
+ g_message ("%s: Unlocking handle %p, offset %ld, length %ld", __func__,
+ handle, offset, length);
#endif
#endif
- return(_wapi_unlock_file_region (file_private_handle->fd, offset,
- length));
+ return(_wapi_unlock_file_region (fd, offset, length));
}