Started moving functions that deal with Unix file descriptors to a
separate fd object. This will be needed for file locking.
diff --git a/server/Makefile.in b/server/Makefile.in
index 543b8e3..bfdc29b 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -16,6 +16,7 @@
debugger.c \
device.c \
event.c \
+ fd.c \
file.c \
handle.c \
hook.c \
diff --git a/server/async.c b/server/async.c
index 5bbbb44..2249fa1 100644
--- a/server/async.c
+++ b/server/async.c
@@ -147,34 +147,3 @@
async->timeout = add_timeout_user( &async->when, async_callback, async );
}
}
-
-DECL_HANDLER(register_async)
-{
- struct object *obj = get_handle_obj( current->process, req->handle, 0, NULL);
-
- if ( !(obj) || !obj->ops->queue_async )
- {
- set_error(STATUS_INVALID_HANDLE);
- return;
- }
-
-/*
- * The queue_async method must do the following:
- *
- * 1. Get the async_queue for the request of given type.
- * 2. Call find_async() to look for the specific client request in the queue (=> NULL if not found).
- * 3. If status is STATUS_PENDING:
- * a) If no async request found in step 2 (new request): call create_async() to initialize one.
- * b) Set request's status to STATUS_PENDING.
- * c) If the "queue" field of the async request is NULL: call async_insert() to put it into the queue.
- * Otherwise:
- * If the async request was found in step 2, destroy it by calling destroy_async().
- * 4. Carry out any operations necessary to adjust the object's poll events
- * Usually: set_elect_events (obj, obj->ops->get_poll_events()).
- *
- * See also the implementations in file.c, serial.c, and sock.c.
-*/
-
- obj->ops->queue_async (obj, req->overlapped, req->status, req->type, req->count);
- release_object(obj);
-}
diff --git a/server/atom.c b/server/atom.c
index 3ab8086..40b07f4 100644
--- a/server/atom.c
+++ b/server/atom.c
@@ -71,12 +71,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satified */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
atom_table_destroy /* destroy */
};
diff --git a/server/change.c b/server/change.c
index a631642..e110ead 100644
--- a/server/change.c
+++ b/server/change.c
@@ -46,12 +46,8 @@
remove_queue, /* remove_queue */
change_signaled, /* signaled */
no_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
no_destroy /* destroy */
};
diff --git a/server/console.c b/server/console.c
index e7e4f31..6288a1a 100644
--- a/server/console.c
+++ b/server/console.c
@@ -51,12 +51,8 @@
remove_queue, /* remove_queue */
console_input_signaled, /* signaled */
no_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
console_get_file_info, /* get_file_info */
- NULL, /* queue_async */
console_input_destroy /* destroy */
};
@@ -80,12 +76,8 @@
remove_queue, /* remove_queue */
console_input_events_signaled, /* signaled */
no_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
console_input_events_destroy /* destroy */
};
@@ -121,12 +113,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
console_get_file_info, /* get_file_info */
- NULL, /* queue_async */
screen_buffer_destroy /* destroy */
};
diff --git a/server/debugger.c b/server/debugger.c
index ba08bd2..0427646 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -72,12 +72,8 @@
remove_queue, /* remove_queue */
debug_event_signaled, /* signaled */
no_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
debug_event_destroy /* destroy */
};
@@ -93,12 +89,8 @@
remove_queue, /* remove_queue */
debug_ctx_signaled, /* signaled */
no_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
debug_ctx_destroy /* destroy */
};
diff --git a/server/device.c b/server/device.c
index 61ead6c..939e6c8 100644
--- a/server/device.c
+++ b/server/device.c
@@ -53,12 +53,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
device_get_info, /* get_file_info */
- NULL, /* queue_async */
no_destroy /* destroy */
};
diff --git a/server/event.c b/server/event.c
index b223487..927e2c7 100644
--- a/server/event.c
+++ b/server/event.c
@@ -50,12 +50,8 @@
remove_queue, /* remove_queue */
event_signaled, /* signaled */
event_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
no_destroy /* destroy */
};
diff --git a/server/fd.c b/server/fd.c
new file mode 100644
index 0000000..1dff6ef
--- /dev/null
+++ b/server/fd.c
@@ -0,0 +1,244 @@
+/*
+ * Server-side file descriptor management
+ *
+ * Copyright (C) 2003 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "object.h"
+#include "file.h"
+#include "handle.h"
+#include "process.h"
+#include "request.h"
+
+struct fd
+{
+ struct object obj; /* object header */
+ const struct fd_ops *fd_ops; /* file descriptor operations */
+ struct object *user; /* object using this file descriptor */
+ int unix_fd; /* unix file descriptor */
+ int mode; /* file protection mode */
+};
+
+static void fd_dump( struct object *obj, int verbose );
+static void fd_destroy( struct object *obj );
+
+static const struct object_ops fd_ops =
+{
+ sizeof(struct fd), /* size */
+ fd_dump, /* dump */
+ no_add_queue, /* add_queue */
+ NULL, /* remove_queue */
+ NULL, /* signaled */
+ NULL, /* satisfied */
+ default_get_fd, /* get_fd */
+ no_get_file_info, /* get_file_info */
+ fd_destroy /* destroy */
+};
+
+
+static void fd_dump( struct object *obj, int verbose )
+{
+ struct fd *fd = (struct fd *)obj;
+ fprintf( stderr, "Fd unix_fd=%d mode=%06o user=%p\n", fd->unix_fd, fd->mode, fd->user );
+}
+
+static void fd_destroy( struct object *obj )
+{
+#if 0
+ struct fd *fd = (struct fd *)obj;
+ close( fd->unix_fd );
+#endif
+}
+
+/* allocate an object that has an associated fd */
+void *alloc_fd_object( const struct object_ops *ops,
+ const struct fd_ops *fd_user_ops, int unix_fd )
+{
+ struct object *user;
+ struct fd *fd = alloc_object( &fd_ops, -1 );
+
+ if (!fd) return NULL;
+ if (!(user = alloc_object( ops, unix_fd )))
+ {
+ release_object( fd );
+ return NULL;
+ }
+ fd->fd_ops = fd_user_ops;
+ fd->user = user;
+ fd->unix_fd = unix_fd;
+ fd->mode = 0;
+
+ user->fd_obj = fd;
+ return user;
+}
+
+/* retrieve the unix fd for an object */
+int get_unix_fd( struct object *obj )
+{
+ struct fd *fd = obj->ops->get_fd( obj );
+ int unix_fd = -1;
+
+ if (fd)
+ {
+ unix_fd = fd->unix_fd;
+ release_object( fd );
+ }
+ return unix_fd;
+}
+
+/* set the unix fd for an object; can only be done once */
+void set_unix_fd( struct object *obj, int unix_fd )
+{
+ struct fd *fd = obj->fd_obj;
+
+ assert( fd );
+ assert( fd->unix_fd == -1 );
+
+ fd->unix_fd = unix_fd;
+ obj->fd = unix_fd;
+}
+
+/* close a file descriptor */
+void close_fd( struct fd *fd )
+{
+ release_object( fd );
+}
+
+/* callback for event happening in the main poll() loop */
+void fd_poll_event( struct object *obj, int event )
+{
+ struct fd *fd = obj->fd_obj;
+ return fd->fd_ops->poll_event( fd->user, event );
+}
+
+/* default add_queue() routine for objects that poll() on an fd */
+int default_fd_add_queue( struct object *obj, struct wait_queue_entry *entry )
+{
+ struct fd *fd = obj->fd_obj;
+
+ if (!obj->head) /* first on the queue */
+ set_select_events( obj, fd->fd_ops->get_poll_events( fd->user ) );
+ add_queue( obj, entry );
+ return 1;
+}
+
+/* default remove_queue() routine for objects that poll() on an fd */
+void default_fd_remove_queue( struct object *obj, struct wait_queue_entry *entry )
+{
+ grab_object( obj );
+ remove_queue( obj, entry );
+ if (!obj->head) /* last on the queue is gone */
+ set_select_events( obj, 0 );
+ release_object( obj );
+}
+
+/* default signaled() routine for objects that poll() on an fd */
+int default_fd_signaled( struct object *obj, struct thread *thread )
+{
+ struct fd *fd = obj->fd_obj;
+ int events = fd->fd_ops->get_poll_events( obj );
+
+ if (check_select_events( fd->unix_fd, events ))
+ {
+ /* stop waiting on select() if we are signaled */
+ set_select_events( obj, 0 );
+ return 1;
+ }
+ /* restart waiting on select() if we are no longer signaled */
+ if (obj->head) set_select_events( obj, events );
+ return 0;
+}
+
+/* default flush() routine */
+int no_flush( struct object *obj )
+{
+ set_error( STATUS_OBJECT_TYPE_MISMATCH );
+ return 0;
+}
+
+/* default queue_async() routine */
+void no_queue_async( struct object *obj, void* ptr, unsigned int status, int type, int count )
+{
+ set_error( STATUS_OBJECT_TYPE_MISMATCH );
+}
+
+/* same as get_handle_obj but retrieve the struct fd associated to the object */
+static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handle,
+ unsigned int access )
+{
+ struct fd *fd = NULL;
+ struct object *obj;
+
+ if ((obj = get_handle_obj( process, handle, 0, NULL )))
+ {
+ if (obj->fd_obj) fd = (struct fd *)grab_object( obj->fd_obj );
+ else set_error( STATUS_OBJECT_TYPE_MISMATCH );
+ release_object( obj );
+ }
+ return fd;
+}
+
+
+/* flush a file buffers */
+DECL_HANDLER(flush_file)
+{
+ struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
+
+ if (fd)
+ {
+ fd->fd_ops->flush( fd->user );
+ release_object( fd );
+ }
+}
+
+/* create / reschedule an async I/O */
+DECL_HANDLER(register_async)
+{
+ struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
+
+/*
+ * The queue_async method must do the following:
+ *
+ * 1. Get the async_queue for the request of given type.
+ * 2. Call find_async() to look for the specific client request in the queue (=> NULL if not found).
+ * 3. If status is STATUS_PENDING:
+ * a) If no async request found in step 2 (new request): call create_async() to initialize one.
+ * b) Set request's status to STATUS_PENDING.
+ * c) If the "queue" field of the async request is NULL: call async_insert() to put it into the queue.
+ * Otherwise:
+ * If the async request was found in step 2, destroy it by calling destroy_async().
+ * 4. Carry out any operations necessary to adjust the object's poll events
+ * Usually: set_elect_events (obj, obj->ops->get_poll_events()).
+ *
+ * See also the implementations in file.c, serial.c, and sock.c.
+*/
+
+ if (fd)
+ {
+ fd->fd_ops->queue_async( fd->user, req->overlapped, req->status, req->type, req->count );
+ release_object( fd );
+ }
+}
diff --git a/server/file.c b/server/file.c
index b302fe6..b4560a8 100644
--- a/server/file.c
+++ b/server/file.c
@@ -40,6 +40,7 @@
#include "winerror.h"
#include "winbase.h"
+#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@@ -65,7 +66,6 @@
static void file_dump( struct object *obj, int verbose );
static int file_get_poll_events( struct object *obj );
static void file_poll_event( struct object *obj, int event );
-static int file_get_fd( struct object *obj );
static int file_flush( struct object *obj );
static int file_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void file_destroy( struct object *obj );
@@ -75,19 +75,23 @@
{
sizeof(struct file), /* size */
file_dump, /* dump */
- default_poll_add_queue, /* add_queue */
- default_poll_remove_queue, /* remove_queue */
- default_poll_signaled, /* signaled */
+ default_fd_add_queue, /* add_queue */
+ default_fd_remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
- file_get_poll_events, /* get_poll_events */
- file_poll_event, /* poll_event */
- file_get_fd, /* get_fd */
- file_flush, /* flush */
+ default_get_fd, /* get_fd */
file_get_info, /* get_file_info */
- file_queue_async, /* queue_async */
file_destroy /* destroy */
};
+static const struct fd_ops file_fd_ops =
+{
+ file_get_poll_events, /* get_poll_events */
+ file_poll_event, /* poll_event */
+ file_flush, /* flush */
+ file_get_info, /* get_file_info */
+ file_queue_async /* queue_async */
+};
static int get_name_hash( const char *name )
{
@@ -127,7 +131,8 @@
unsigned int attrs, int drive_type )
{
struct file *file;
- if ((file = alloc_object( &file_ops, fd )))
+
+ if ((file = alloc_fd_object( &file_ops, &file_fd_ops, fd )))
{
file->name = NULL;
file->next = NULL;
@@ -291,22 +296,10 @@
}
-static int file_get_fd( struct object *obj )
-{
- struct file *file = (struct file *)obj;
- assert( obj->ops == &file_ops );
- return file->obj.fd;
-}
-
static int file_flush( struct object *obj )
{
- int ret;
- struct file *file = (struct file *)grab_object(obj);
- assert( obj->ops == &file_ops );
-
- ret = (fsync( file->obj.fd ) != -1);
+ int ret = (fsync( get_unix_fd(obj) ) != -1);
if (!ret) file_set_error();
- release_object( file );
return ret;
}
@@ -314,17 +307,17 @@
{
struct stat st;
struct file *file = (struct file *)obj;
- assert( obj->ops == &file_ops );
+ int unix_fd = get_unix_fd( obj );
if (reply)
{
- if (fstat( file->obj.fd, &st ) == -1)
+ if (fstat( unix_fd, &st ) == -1)
{
file_set_error();
return FD_TYPE_INVALID;
}
if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
- S_ISSOCK(st.st_mode) || isatty(file->obj.fd)) reply->type = FILE_TYPE_CHAR;
+ S_ISSOCK(st.st_mode) || isatty(unix_fd)) reply->type = FILE_TYPE_CHAR;
else reply->type = FILE_TYPE_DISK;
if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
@@ -394,7 +387,7 @@
async_insert( q, async );
/* Check if the new pending request can be served immediately */
- pfd.fd = obj->fd;
+ pfd.fd = get_unix_fd( obj );
pfd.events = file_get_poll_events ( obj );
pfd.revents = 0;
poll ( &pfd, 1, 0 );
@@ -469,7 +462,7 @@
xto = *low+((off_t)*high<<32);
if (!(file = get_file_obj( current->process, handle, 0 )))
return 0;
- if ((result = lseek(file->obj.fd,xto,whence))==-1)
+ if ((result = lseek( get_unix_fd(&file->obj), xto, whence))==-1)
{
/* Check for seek before start of file */
@@ -492,13 +485,14 @@
static int extend_file( struct file *file, off_t size )
{
static const char zero;
+ int unix_fd = get_unix_fd( &file->obj );
/* extend the file one byte beyond the requested size and then truncate it */
/* this should work around ftruncate implementations that can't extend files */
- if ((lseek( file->obj.fd, size, SEEK_SET ) != -1) &&
- (write( file->obj.fd, &zero, 1 ) != -1))
+ if ((lseek( unix_fd, size, SEEK_SET ) != -1) &&
+ (write( unix_fd, &zero, 1 ) != -1))
{
- ftruncate( file->obj.fd, size );
+ ftruncate( unix_fd, size );
return 1;
}
file_set_error();
@@ -509,16 +503,17 @@
static int truncate_file( struct file *file )
{
int ret = 0;
- off_t pos = lseek( file->obj.fd, 0, SEEK_CUR );
- off_t eof = lseek( file->obj.fd, 0, SEEK_END );
+ int unix_fd = get_unix_fd( &file->obj );
+ off_t pos = lseek( unix_fd, 0, SEEK_CUR );
+ off_t eof = lseek( unix_fd, 0, SEEK_END );
if (eof < pos) ret = extend_file( file, pos );
else
{
- if (ftruncate( file->obj.fd, pos ) != -1) ret = 1;
+ if (ftruncate( unix_fd, pos ) != -1) ret = 1;
else file_set_error();
}
- lseek( file->obj.fd, pos, SEEK_SET ); /* restore file pos */
+ lseek( unix_fd, pos, SEEK_SET ); /* restore file pos */
return ret;
}
@@ -527,17 +522,18 @@
{
int ret = 0;
struct stat st;
+ int unix_fd = get_unix_fd( &file->obj );
off_t old_pos, size = size_low + (((off_t)size_high)<<32);
- if (fstat( file->obj.fd, &st ) == -1)
+ if (fstat( unix_fd, &st ) == -1)
{
file_set_error();
return 0;
}
if (st.st_size >= size) return 1; /* already large enough */
- old_pos = lseek( file->obj.fd, 0, SEEK_CUR ); /* save old pos */
+ old_pos = lseek( unix_fd, 0, SEEK_CUR ); /* save old pos */
ret = extend_file( file, size );
- lseek( file->obj.fd, old_pos, SEEK_SET ); /* restore file pos */
+ lseek( unix_fd, old_pos, SEEK_SET ); /* restore file pos */
return ret;
}
@@ -633,8 +629,8 @@
if (fd != -1) reply->fd = fd;
else if (!get_error())
{
- if ((fd = obj->ops->get_fd( obj )) != -1)
- send_client_fd( current->process, fd, req->handle );
+ int unix_fd = get_unix_fd( obj );
+ if (unix_fd != -1) send_client_fd( current->process, unix_fd, req->handle );
}
reply->type = obj->ops->get_file_info( obj, NULL, &reply->flags );
release_object( obj );
@@ -663,18 +659,6 @@
}
}
-/* flush a file buffers */
-DECL_HANDLER(flush_file)
-{
- struct object *obj;
-
- if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
- {
- obj->ops->flush( obj );
- release_object( obj );
- }
-}
-
/* set a file access and modification times */
DECL_HANDLER(set_file_time)
{
diff --git a/server/file.h b/server/file.h
new file mode 100644
index 0000000..f5c9a32
--- /dev/null
+++ b/server/file.h
@@ -0,0 +1,56 @@
+/*
+ * Server-side file definitions
+ *
+ * Copyright (C) 2003 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_SERVER_FILE_H
+#define __WINE_SERVER_FILE_H
+
+#include "object.h"
+
+struct fd;
+
+/* operations valid on file descriptor objects */
+struct fd_ops
+{
+ /* get the events we want to poll() for on this object */
+ int (*get_poll_events)(struct object *);
+ /* a poll() event occured */
+ void (*poll_event)(struct object *,int event);
+ /* flush the object buffers */
+ int (*flush)(struct object *);
+ /* get file information */
+ int (*get_file_info)(struct object *,struct get_file_info_reply *, int *flags);
+ /* queue an async operation - see register_async handler in async.c*/
+ void (*queue_async)(struct object *, void* ptr, unsigned int status, int type, int count);
+};
+
+extern void *alloc_fd_object( const struct object_ops *ops,
+ const struct fd_ops *fd_user_ops, int unix_fd );
+extern int get_unix_fd( struct object *obj );
+extern void set_unix_fd( struct object *obj, int unix_fd );
+extern void close_fd( struct fd *fd );
+extern void fd_poll_event( struct object *obj, int event );
+
+extern int default_fd_add_queue( struct object *obj, struct wait_queue_entry *entry );
+extern void default_fd_remove_queue( struct object *obj, struct wait_queue_entry *entry );
+extern int default_fd_signaled( struct object *obj, struct thread *thread );
+extern int no_flush( struct object *obj );
+extern void no_queue_async(struct object *obj, void* ptr, unsigned int status, int type, int count);
+
+#endif /* __WINE_SERVER_FILE_H */
diff --git a/server/handle.c b/server/handle.c
index 9df4293..471d5a7 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -104,12 +104,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
handle_table_destroy /* destroy */
};
diff --git a/server/hook.c b/server/hook.c
index 3a483c1..d10318d 100644
--- a/server/hook.c
+++ b/server/hook.c
@@ -66,12 +66,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
hook_table_destroy /* destroy */
};
diff --git a/server/mapping.c b/server/mapping.c
index b7b055c..4881bc7 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -28,6 +28,7 @@
#include "winbase.h"
+#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@@ -47,7 +48,7 @@
struct mapping *shared_prev; /* prev in shared PE mapping list */
};
-static int mapping_get_fd( struct object *obj );
+static struct fd *mapping_get_fd( struct object *obj );
static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void mapping_dump( struct object *obj, int verbose );
static void mapping_destroy( struct object *obj );
@@ -60,12 +61,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
mapping_get_fd, /* get_fd */
- no_flush, /* flush */
mapping_get_info, /* get_file_info */
- NULL, /* queue_async */
mapping_destroy /* destroy */
};
@@ -111,13 +108,7 @@
/* get the fd to use for mmaping a file */
inline static int get_mmap_fd( struct file *file )
{
- struct object *obj;
- if (!(obj = (struct object *)file))
- {
- set_error( STATUS_INVALID_HANDLE );
- return -1;
- }
- return obj->ops->get_fd( obj );
+ return get_unix_fd( (struct object *)file );
}
/* find the shared PE mapping for a given mapping */
@@ -327,11 +318,12 @@
fputc( '\n', stderr );
}
-static int mapping_get_fd( struct object *obj )
+static struct fd *mapping_get_fd( struct object *obj )
{
struct mapping *mapping = (struct mapping *)obj;
assert( obj->ops == &mapping_ops );
- return get_mmap_fd( mapping->file );
+
+ return default_get_fd( (struct object *)mapping->file );
}
static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
diff --git a/server/mutex.c b/server/mutex.c
index fe76553..9ca844e 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -54,12 +54,8 @@
remove_queue, /* remove_queue */
mutex_signaled, /* signaled */
mutex_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
mutex_destroy /* destroy */
};
diff --git a/server/named_pipe.c b/server/named_pipe.c
index fab8188..f2323cc 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -38,6 +38,7 @@
#include "winbase.h"
+#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@@ -90,35 +91,35 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
named_pipe_destroy /* destroy */
};
static void pipe_user_dump( struct object *obj, int verbose );
static void pipe_user_destroy( struct object *obj);
-static int pipe_user_get_fd( struct object *obj );
static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static const struct object_ops pipe_user_ops =
{
sizeof(struct pipe_user), /* size */
pipe_user_dump, /* dump */
- default_poll_add_queue, /* add_queue */
- default_poll_remove_queue, /* remove_queue */
- default_poll_signaled, /* signaled */
+ default_fd_add_queue, /* add_queue */
+ default_fd_remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
+ default_get_fd, /* get_fd */
+ pipe_user_get_info, /* get_file_info */
+ pipe_user_destroy /* destroy */
+};
+
+static const struct fd_ops pipe_user_fd_ops =
+{
NULL, /* get_poll_events */
default_poll_event, /* poll_event */
- pipe_user_get_fd, /* get_fd */
no_flush, /* flush */
pipe_user_get_info, /* get_file_info */
- NULL, /* queue_async */
- pipe_user_destroy /* destroy */
+ no_queue_async /* queue_async */
};
static void named_pipe_dump( struct object *obj, int verbose )
@@ -192,13 +193,6 @@
release_object(user->pipe);
}
-static int pipe_user_get_fd( struct object *obj )
-{
- struct pipe_user *user = (struct pipe_user *)obj;
- assert( obj->ops == &pipe_user_ops );
- return user->obj.fd;
-}
-
static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
if (reply)
@@ -243,7 +237,7 @@
{
struct pipe_user *user;
- user = alloc_object( &pipe_user_ops, fd );
+ user = alloc_fd_object( &pipe_user_ops, &pipe_user_fd_ops, fd );
if(!user)
return NULL;
@@ -475,4 +469,3 @@
release_object(user);
}
-
diff --git a/server/object.c b/server/object.c
index 600c040..77e1162 100644
--- a/server/object.c
+++ b/server/object.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <unistd.h>
+#include "file.h"
#include "thread.h"
#include "unicode.h"
#include "list.h"
@@ -137,6 +138,7 @@
if (obj)
{
obj->refcount = 1;
+ obj->fd_obj = NULL;
obj->fd = fd;
obj->select = -1;
obj->ops = ops;
@@ -218,6 +220,7 @@
assert( !obj->head );
assert( !obj->tail );
obj->ops->destroy( obj );
+ if (obj->fd_obj) close_fd( obj->fd_obj );
if (obj->name) free_name( obj );
if (obj->select != -1) remove_select_user( obj );
if (obj->fd != -1) close( obj->fd );
@@ -287,16 +290,17 @@
return 0; /* not abandoned */
}
-int no_get_fd( struct object *obj )
+struct fd *no_get_fd( struct object *obj )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
- return -1;
+ return NULL;
}
-int no_flush( struct object *obj )
+struct fd *default_get_fd( struct object *obj )
{
+ if (obj->fd_obj) return (struct fd *)grab_object( obj->fd_obj );
set_error( STATUS_OBJECT_TYPE_MISMATCH );
- return 0;
+ return NULL;
}
int no_get_file_info( struct object *obj, struct get_file_info_reply *info, int *flags )
@@ -310,41 +314,6 @@
{
}
-/* default add_queue() routine for objects that poll() on an fd */
-int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry )
-{
- if (!obj->head) /* first on the queue */
- set_select_events( obj, obj->ops->get_poll_events( obj ) );
- add_queue( obj, entry );
- return 1;
-}
-
-/* default remove_queue() routine for objects that poll() on an fd */
-void default_poll_remove_queue( struct object *obj, struct wait_queue_entry *entry )
-{
- grab_object(obj);
- remove_queue( obj, entry );
- if (!obj->head) /* last on the queue is gone */
- set_select_events( obj, 0 );
- release_object( obj );
-}
-
-/* default signaled() routine for objects that poll() on an fd */
-int default_poll_signaled( struct object *obj, struct thread *thread )
-{
- int events = obj->ops->get_poll_events( obj );
-
- if (check_select_events( obj->fd, events ))
- {
- /* stop waiting on select() if we are signaled */
- set_select_events( obj, 0 );
- return 1;
- }
- /* restart waiting on select() if we are no longer signaled */
- if (obj->head) set_select_events( obj, events );
- return 0;
-}
-
/* default handler for poll() events */
void default_poll_event( struct object *obj, int event )
{
diff --git a/server/object.h b/server/object.h
index 711f584..7868e2f 100644
--- a/server/object.h
+++ b/server/object.h
@@ -55,18 +55,10 @@
int (*signaled)(struct object *,struct thread *);
/* wait satisfied; return 1 if abandoned */
int (*satisfied)(struct object *,struct thread *);
- /* get the events we want to poll() for on this object */
- int (*get_poll_events)(struct object *);
- /* a poll() event occured */
- void (*poll_event)(struct object *,int event);
- /* return a Unix fd that can be used to read/write from the object */
- int (*get_fd)(struct object *);
- /* flush the object buffers */
- int (*flush)(struct object *);
+ /* return an fd object that can be used to read/write from the object */
+ struct fd *(*get_fd)(struct object *);
/* get file information */
int (*get_file_info)(struct object *,struct get_file_info_reply *, int *flags);
- /* queue an async operation - see register_async handler in async.c*/
- void (*queue_async)(struct object *, void* ptr, unsigned int status, int type, int count);
/* destroy on refcount == 0 */
void (*destroy)(struct object *);
};
@@ -74,6 +66,7 @@
struct object
{
unsigned int refcount; /* reference count */
+ struct fd *fd_obj; /* file descriptor */
int fd; /* file descriptor */
int select; /* select() user id */
const struct object_ops *ops;
@@ -107,13 +100,10 @@
extern struct object *find_object( const struct namespace *namespace, const WCHAR *name, size_t len );
extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry );
extern int no_satisfied( struct object *obj, struct thread *thread );
-extern int no_get_fd( struct object *obj );
-extern int no_flush( struct object *obj );
+extern struct fd *no_get_fd( struct object *obj );
+extern struct fd *default_get_fd( struct object *obj );
extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info, int *flags );
extern void no_destroy( struct object *obj );
-extern int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry );
-extern void default_poll_remove_queue( struct object *obj, struct wait_queue_entry *entry );
-extern int default_poll_signaled( struct object *obj, struct thread *thread );
extern void default_poll_event( struct object *obj, int event );
#ifdef DEBUG_OBJECTS
extern void dump_objects(void);
diff --git a/server/pipe.c b/server/pipe.c
index ce6f11a..4f57a2f 100644
--- a/server/pipe.c
+++ b/server/pipe.c
@@ -32,6 +32,7 @@
#include "winbase.h"
+#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@@ -47,7 +48,7 @@
static void pipe_dump( struct object *obj, int verbose );
static int pipe_get_poll_events( struct object *obj );
-static int pipe_get_fd( struct object *obj );
+static struct fd *pipe_get_fd( struct object *obj );
static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void pipe_destroy( struct object *obj );
@@ -55,17 +56,22 @@
{
sizeof(struct pipe), /* size */
pipe_dump, /* dump */
- default_poll_add_queue, /* add_queue */
- default_poll_remove_queue, /* remove_queue */
- default_poll_signaled, /* signaled */
+ default_fd_add_queue, /* add_queue */
+ default_fd_remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
+ pipe_get_fd, /* get_fd */
+ pipe_get_info, /* get_file_info */
+ pipe_destroy /* destroy */
+};
+
+static const struct fd_ops pipe_fd_ops =
+{
pipe_get_poll_events, /* get_poll_events */
default_poll_event, /* poll_event */
- pipe_get_fd, /* get_fd */
no_flush, /* flush */
pipe_get_info, /* get_file_info */
- NULL, /* queue_async */
- pipe_destroy /* destroy */
+ no_queue_async /* queue_async */
};
@@ -73,7 +79,7 @@
{
struct pipe *pipe;
- if ((pipe = alloc_object( &pipe_ops, fd )))
+ if ((pipe = alloc_fd_object( &pipe_ops, &pipe_fd_ops, fd )))
{
pipe->other = NULL;
pipe->side = side;
@@ -123,7 +129,7 @@
return (pipe->side == READ_SIDE) ? POLLIN : POLLOUT;
}
-static int pipe_get_fd( struct object *obj )
+static struct fd *pipe_get_fd( struct object *obj )
{
struct pipe *pipe = (struct pipe *)obj;
assert( obj->ops == &pipe_ops );
@@ -131,9 +137,9 @@
if (!pipe->other)
{
set_error( STATUS_PIPE_BROKEN );
- return -1;
+ return NULL;
}
- return pipe->obj.fd;
+ return (struct fd *)grab_object( pipe->obj.fd_obj );
}
static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
diff --git a/server/process.c b/server/process.c
index 7d66d1b..8319129 100644
--- a/server/process.c
+++ b/server/process.c
@@ -36,6 +36,7 @@
#include "winbase.h"
#include "winnt.h"
+#include "file.h"
#include "handle.h"
#include "process.h"
#include "thread.h"
@@ -62,13 +63,18 @@
remove_queue, /* remove_queue */
process_signaled, /* signaled */
no_satisfied, /* satisfied */
+ no_get_fd, /* get_fd */
+ no_get_file_info, /* get_file_info */
+ process_destroy /* destroy */
+};
+
+static const struct fd_ops process_fd_ops =
+{
NULL, /* get_poll_events */
process_poll_event, /* poll_event */
- no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
- process_destroy /* destroy */
+ no_queue_async /* queue_async */
};
/* process startup info */
@@ -102,12 +108,8 @@
remove_queue, /* remove_queue */
startup_info_signaled, /* signaled */
no_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
startup_info_destroy /* destroy */
};
@@ -190,7 +192,7 @@
struct thread *thread = NULL;
int request_pipe[2];
- if (!(process = alloc_object( &process_ops, fd ))) goto error;
+ if (!(process = alloc_fd_object( &process_ops, &process_fd_ops, fd ))) goto error;
process->next = NULL;
process->prev = NULL;
process->parent = NULL;
diff --git a/server/queue.c b/server/queue.c
index 8eaba4d..39c0d0e 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -143,12 +143,8 @@
msg_queue_remove_queue, /* remove_queue */
msg_queue_signaled, /* signaled */
msg_queue_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
msg_queue_destroy /* destroy */
};
@@ -161,12 +157,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
thread_input_destroy /* destroy */
};
diff --git a/server/registry.c b/server/registry.c
index 31dfe97..5b75b50 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -37,7 +37,9 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
+
#include "object.h"
+#include "file.h"
#include "handle.h"
#include "request.h"
#include "unicode.h"
@@ -166,12 +168,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
key_destroy /* destroy */
};
@@ -1452,7 +1450,7 @@
int fd;
if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL ))) return;
- fd = dup(obj->ops->get_fd( obj ));
+ fd = dup( get_unix_fd( obj ) );
release_object( obj );
if (fd != -1)
{
@@ -1547,7 +1545,7 @@
return;
}
if (!(obj = get_handle_obj( current->process, handle, GENERIC_WRITE, NULL ))) return;
- fd = dup(obj->ops->get_fd( obj ));
+ fd = dup( get_unix_fd( obj ) );
release_object( obj );
if (fd != -1)
{
diff --git a/server/request.c b/server/request.c
index ff1450b..98bec45 100644
--- a/server/request.c
+++ b/server/request.c
@@ -48,6 +48,7 @@
#include "wincon.h"
#include "wine/library.h"
+#include "file.h"
#include "handle.h"
#include "thread.h"
#include "process.h"
@@ -81,13 +82,18 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
+ no_get_fd, /* get_fd */
+ no_get_file_info, /* get_file_info */
+ no_destroy /* destroy */
+};
+
+static const struct fd_ops master_socket_fd_ops =
+{
NULL, /* get_poll_events */
master_socket_poll_event, /* poll_event */
- no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
- no_destroy /* destroy */
+ no_queue_async /* queue_async */
};
@@ -670,7 +676,7 @@
chmod( server_socket_name, 0600 ); /* make sure no other user can connect */
if (listen( fd, 5 ) == -1) fatal_perror( "listen" );
- if (!(master_socket = alloc_object( &master_socket_ops, fd )))
+ if (!(master_socket = alloc_fd_object( &master_socket_ops, &master_socket_fd_ops, fd )))
fatal_error( "out of memory\n" );
master_socket->timeout = NULL;
set_select_events( &master_socket->obj, POLLIN );
diff --git a/server/select.c b/server/select.c
index 9b70d04..2ea2354 100644
--- a/server/select.c
+++ b/server/select.c
@@ -28,7 +28,7 @@
#include <sys/types.h>
#include <unistd.h>
-#include "object.h"
+#include "file.h"
#include "thread.h"
#include "process.h"
@@ -301,7 +301,7 @@
{
if (pollfd[i].revents)
{
- poll_users[i]->ops->poll_event( poll_users[i], pollfd[i].revents );
+ fd_poll_event( poll_users[i], pollfd[i].revents );
if (!--ret) break;
}
}
diff --git a/server/semaphore.c b/server/semaphore.c
index ee90988..3f5e953 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -50,12 +50,8 @@
remove_queue, /* remove_queue */
semaphore_signaled, /* signaled */
semaphore_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
no_destroy /* destroy */
};
diff --git a/server/serial.c b/server/serial.c
index 22c336f..0e4d79f 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -39,13 +39,13 @@
#include "winerror.h"
#include "winbase.h"
+#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
#include "async.h"
static void serial_dump( struct object *obj, int verbose );
-static int serial_get_fd( struct object *obj );
static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static int serial_get_poll_events( struct object *obj );
static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count);
@@ -82,17 +82,22 @@
{
sizeof(struct serial), /* size */
serial_dump, /* dump */
- default_poll_add_queue, /* add_queue */
- default_poll_remove_queue, /* remove_queue */
- default_poll_signaled, /* signaled */
+ default_fd_add_queue, /* add_queue */
+ default_fd_remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
+ default_get_fd, /* get_fd */
+ serial_get_info, /* get_file_info */
+ destroy_serial /* destroy */
+};
+
+static const struct fd_ops serial_fd_ops =
+{
serial_get_poll_events, /* get_poll_events */
serial_poll_event, /* poll_event */
- serial_get_fd, /* get_fd */
serial_flush, /* flush */
serial_get_info, /* get_file_info */
- serial_queue_async, /* queue_async */
- destroy_serial /* destroy */
+ serial_queue_async /* queue_async */
};
static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access, int attributes )
@@ -137,7 +142,7 @@
if(0>fcntl(fd, F_SETFL, 0))
perror("fcntl");
- if ((serial = alloc_object( &serial_ops, fd )))
+ if ((serial = alloc_fd_object( &serial_ops, &serial_fd_ops, fd )))
{
serial->attrib = attributes;
serial->access = access;
@@ -194,13 +199,6 @@
return events;
}
-static int serial_get_fd( struct object *obj )
-{
- struct serial *serial = (struct serial *)obj;
- assert( obj->ops == &serial_ops );
- return serial->obj.fd;
-}
-
static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
struct serial *serial = (struct serial *) obj;
@@ -245,7 +243,7 @@
if(IS_READY(serial->wait_q) && (POLLIN & event) )
async_notify(serial->wait_q.head,STATUS_ALERTED);
- set_select_events(obj,obj->ops->get_poll_events(obj));
+ set_select_events( obj, serial_get_poll_events(obj) );
}
static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count)
@@ -295,7 +293,7 @@
}
/* Check if the new pending request can be served immediately */
- pfd.fd = obj->fd;
+ pfd.fd = get_unix_fd( obj );
pfd.events = serial_get_poll_events ( obj );
pfd.revents = 0;
poll ( &pfd, 1, 0 );
@@ -315,16 +313,11 @@
static int serial_flush( struct object *obj )
{
- int ret;
- struct serial *serial = (struct serial *)grab_object(obj);
- assert( obj->ops == &serial_ops );
-
/* MSDN says: If hFile is a handle to a communications device,
* the function only flushes the transmit buffer.
*/
- ret = (tcflush( serial->obj.fd, TCOFLUSH ) != -1);
+ int ret = (tcflush( get_unix_fd(obj), TCOFLUSH ) != -1);
if (!ret) file_set_error();
- release_object( serial );
return ret;
}
diff --git a/server/smb.c b/server/smb.c
index e924774..ab00685 100644
--- a/server/smb.c
+++ b/server/smb.c
@@ -40,12 +40,12 @@
#include "winerror.h"
#include "winbase.h"
+#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
static void smb_dump( struct object *obj, int verbose );
-static int smb_get_fd( struct object *obj );
static int smb_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static int smb_get_poll_events( struct object *obj );
static void destroy_smb(struct object *obj);
@@ -64,17 +64,22 @@
{
sizeof(struct smb), /* size */
smb_dump, /* dump */
- default_poll_add_queue, /* add_queue */
- default_poll_remove_queue, /* remove_queue */
- default_poll_signaled, /* signaled */
+ default_fd_add_queue, /* add_queue */
+ default_fd_remove_queue, /* remove_queue */
+ default_fd_signaled, /* signaled */
no_satisfied, /* satisfied */
+ default_get_fd, /* get_fd */
+ smb_get_info, /* get_file_info */
+ destroy_smb /* destroy */
+};
+
+static const struct fd_ops smb_fd_ops =
+{
smb_get_poll_events, /* get_poll_events */
default_poll_event, /* poll_event */
- smb_get_fd, /* get_fd */
no_flush, /* flush */
smb_get_info, /* get_file_info */
- NULL, /* queue_async */
- destroy_smb /* destroy */
+ no_queue_async /* queue_async */
};
static void destroy_smb( struct object *obj)
@@ -108,13 +113,6 @@
return events;
}
-static int smb_get_fd( struct object *obj )
-{
- struct smb *smb = (struct smb *)obj;
- assert( obj->ops == &smb_ops );
- return smb->obj.fd;
-}
-
static int smb_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
/* struct smb *smb = (struct smb *) obj; */
@@ -154,7 +152,7 @@
return;
}
- smb = alloc_object( &smb_ops, fd );
+ smb = alloc_fd_object( &smb_ops, &smb_fd_ops, fd );
if (smb)
{
smb->tree_id = req->tree_id;
diff --git a/server/snapshot.c b/server/snapshot.c
index 0df1ac4..90a8bf4 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -61,12 +61,8 @@
NULL, /* remove_queue */
NULL, /* signaled */
NULL, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
snapshot_destroy /* destroy */
};
diff --git a/server/sock.c b/server/sock.c
index 05324b9..d528ab5 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -44,9 +44,10 @@
#include <time.h>
#include <unistd.h>
-#include "winerror.h"
#include "winbase.h"
+
#include "process.h"
+#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
@@ -83,7 +84,6 @@
static int sock_signaled( struct object *obj, struct thread *thread );
static int sock_get_poll_events( struct object *obj );
static void sock_poll_event( struct object *obj, int event );
-static int sock_get_fd( struct object *obj );
static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static void sock_destroy( struct object *obj );
static int sock_get_error( int err );
@@ -98,13 +98,18 @@
remove_queue, /* remove_queue */
sock_signaled, /* signaled */
no_satisfied, /* satisfied */
+ default_get_fd, /* get_fd */
+ sock_get_info, /* get_file_info */
+ sock_destroy /* destroy */
+};
+
+static const struct fd_ops sock_fd_ops =
+{
sock_get_poll_events, /* get_poll_events */
sock_poll_event, /* poll_event */
- sock_get_fd, /* get_fd */
no_flush, /* flush */
sock_get_info, /* get_file_info */
- sock_queue_async, /* queue_async */
- sock_destroy /* destroy */
+ sock_queue_async /* queue_async */
};
@@ -438,7 +443,7 @@
struct sock *sock = (struct sock *)obj;
assert( obj->ops == &sock_ops );
- return check_select_events( sock->obj.fd, sock_get_poll_events( &sock->obj ) );
+ return check_select_events( get_unix_fd(obj), sock_get_poll_events( &sock->obj ) );
}
static int sock_get_poll_events( struct object *obj )
@@ -467,13 +472,6 @@
return ev;
}
-static int sock_get_fd( struct object *obj )
-{
- struct sock *sock = (struct sock *)obj;
- assert( obj->ops == &sock_ops );
- return sock->obj.fd;
-}
-
static int sock_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
struct sock *sock = (struct sock*) obj;
@@ -592,8 +590,8 @@
return NULL;
}
fcntl(sockfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
- if (!(sock = alloc_object( &sock_ops, -1 ))) return NULL;
- sock->obj.fd = sockfd;
+ if (!(sock = alloc_fd_object( &sock_ops, &sock_fd_ops, -1 ))) return NULL;
+ set_unix_fd( &sock->obj, sockfd );
sock->state = (type != SOCK_STREAM) ? (FD_READ|FD_WRITE) : 0;
sock->mask = 0;
sock->hmask = 0;
@@ -640,13 +638,13 @@
* return.
*/
slen = sizeof(saddr);
- acceptfd = accept(sock->obj.fd,&saddr,&slen);
+ acceptfd = accept( get_unix_fd(&sock->obj), &saddr, &slen);
if (acceptfd==-1) {
sock_set_error();
release_object( sock );
return NULL;
}
- if (!(acceptsock = alloc_object( &sock_ops, -1 )))
+ if (!(acceptsock = alloc_fd_object( &sock_ops, &sock_fd_ops, acceptfd )))
{
release_object( sock );
return NULL;
@@ -654,7 +652,6 @@
/* newly created socket gets the same properties of the listening socket */
fcntl(acceptfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
- acceptsock->obj.fd = acceptfd;
acceptsock->state = FD_WINE_CONNECTED|FD_READ|FD_WRITE;
if (sock->state & FD_WINE_NONBLOCKING)
acceptsock->state |= FD_WINE_NONBLOCKING;
diff --git a/server/thread.c b/server/thread.c
index f8396e0..dceeef4 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -35,6 +35,7 @@
#include "winbase.h"
+#include "file.h"
#include "handle.h"
#include "process.h"
#include "thread.h"
@@ -86,13 +87,18 @@
remove_queue, /* remove_queue */
thread_signaled, /* signaled */
no_satisfied, /* satisfied */
+ no_get_fd, /* get_fd */
+ no_get_file_info, /* get_file_info */
+ destroy_thread /* destroy */
+};
+
+static const struct fd_ops thread_fd_ops =
+{
NULL, /* get_poll_events */
thread_poll_event, /* poll_event */
- no_get_fd, /* get_fd */
no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
- destroy_thread /* destroy */
+ no_queue_async /* queue_async */
};
static struct thread *first_thread;
@@ -144,7 +150,7 @@
{
struct thread *thread;
- if (!(thread = alloc_object( &thread_ops, fd ))) return NULL;
+ if (!(thread = alloc_fd_object( &thread_ops, &thread_fd_ops, fd ))) return NULL;
init_thread_structure( thread );
diff --git a/server/timer.c b/server/timer.c
index ddc137d..2d48fc6 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -57,12 +57,8 @@
remove_queue, /* remove_queue */
timer_signaled, /* signaled */
timer_satisfied, /* satisfied */
- NULL, /* get_poll_events */
- NULL, /* poll_event */
no_get_fd, /* get_fd */
- no_flush, /* flush */
no_get_file_info, /* get_file_info */
- NULL, /* queue_async */
timer_destroy /* destroy */
};