Added serial port object to the server.
diff --git a/server/Makefile.in b/server/Makefile.in
index 12fd8de..6563b32 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -28,6 +28,7 @@
request.c \
select.c \
semaphore.c \
+ serial.c \
snapshot.c \
sock.c \
thread.c \
diff --git a/server/request.h b/server/request.h
index bf9b797..d66c230 100644
--- a/server/request.h
+++ b/server/request.h
@@ -201,6 +201,7 @@
DECL_HANDLER(get_msg_queue);
DECL_HANDLER(wake_queue);
DECL_HANDLER(wait_input_idle);
+DECL_HANDLER(create_serial);
#ifdef WANT_REQUEST_HANDLERS
@@ -314,6 +315,7 @@
(req_handler)req_get_msg_queue,
(req_handler)req_wake_queue,
(req_handler)req_wait_input_idle,
+ (req_handler)req_create_serial,
};
#endif /* WANT_REQUEST_HANDLERS */
diff --git a/server/serial.c b/server/serial.c
new file mode 100644
index 0000000..e5b6066
--- /dev/null
+++ b/server/serial.c
@@ -0,0 +1,198 @@
+/*
+ * Server-side serial port communications management
+ *
+ * Copyright (C) 1998 Alexandre Julliard
+ * Copyright (C) 2000 Mike McCormack
+ *
+ * TODO:
+ * Add async read, write and WaitCommEvent handling.
+ *
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef HAVE_SYS_ERRNO_H
+#include <sys/errno.h>
+#endif
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <utime.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include "winerror.h"
+#include "winbase.h"
+
+#include "handle.h"
+#include "thread.h"
+#include "request.h"
+
+static void serial_dump( struct object *obj, int verbose );
+static void serial_destroy( struct object *obj );
+static int serial_get_read_fd( struct object *obj );
+static int serial_get_write_fd( struct object *obj );
+static int serial_get_info( struct object *obj, struct get_file_info_request *req );
+static int serial_get_poll_events( struct object *obj );
+
+struct serial
+{
+ struct object obj;
+ char name[16]; /* eg. /dev/ttyS1 */
+ int access;
+
+ /* timeout values */
+ unsigned int readinterval;
+ unsigned int readconst;
+ unsigned int readmult;
+ unsigned int writeconst;
+ unsigned int writemult;
+
+ unsigned int eventmask;
+ unsigned int commerror;
+
+ struct termios original;
+
+ /* FIXME: add dcb, comm status, handler module, sharing */
+};
+
+static const struct object_ops serial_ops =
+{
+ sizeof(struct serial), /* size */
+ serial_dump, /* dump */
+ default_poll_add_queue, /* add_queue */
+ default_poll_remove_queue, /* remove_queue */
+ default_poll_signaled, /* signaled */
+ no_satisfied, /* satisfied */
+ serial_get_poll_events, /* get_poll_events */
+ default_poll_event, /* poll_event */
+ serial_get_read_fd, /* get_read_fd */
+ serial_get_write_fd, /* get_write_fd */
+ no_flush, /* flush */
+ serial_get_info, /* get_file_info */
+ serial_destroy /* destroy */
+};
+
+/* SERIAL PORT functions */
+
+static void serial_dump( struct object *obj, int verbose )
+{
+ struct serial *serial = (struct serial *)obj;
+ assert( obj->ops == &serial_ops );
+
+ fprintf( stderr, "Port fd=%d name='%s' mask=%x\n",
+ serial->obj.fd, serial->name,serial->eventmask);
+}
+
+/* same as file_destroy, but don't delete comm ports */
+static void serial_destroy( struct object *obj )
+{
+ assert( obj->ops == &serial_ops );
+}
+
+struct serial *get_serial_obj( struct process *process, int handle, unsigned int access )
+{
+ return (struct serial *)get_handle_obj( process, handle, access, &serial_ops );
+}
+
+static int serial_get_poll_events( struct object *obj )
+{
+ struct serial *serial = (struct serial *)obj;
+ int events = 0;
+ assert( obj->ops == &serial_ops );
+ if (serial->access & GENERIC_READ) events |= POLLIN;
+ if (serial->access & GENERIC_WRITE) events |= POLLOUT;
+ return events;
+}
+
+static int serial_get_read_fd( struct object *obj )
+{
+ struct serial *serial = (struct serial *)obj;
+ assert( obj->ops == &serial_ops );
+ return dup( serial->obj.fd );
+}
+
+static int serial_get_write_fd( struct object *obj )
+{
+ struct serial *serial = (struct serial *)obj;
+ assert( obj->ops == &serial_ops );
+ return dup( serial->obj.fd );
+}
+
+static int serial_get_info( struct object *obj, struct get_file_info_request *req )
+{
+ assert( obj->ops == &serial_ops );
+ req->type = FILE_TYPE_CHAR;
+ req->attr = 0;
+ req->access_time = 0;
+ req->write_time = 0;
+ req->size_high = 0;
+ req->size_low = 0;
+ req->links = 0;
+ req->index_high = 0;
+ req->index_low = 0;
+ req->serial = 0;
+ return 1;
+}
+
+/* create a serial */
+DECL_HANDLER(create_serial)
+{
+ struct serial *serial;
+ int fd,flags;
+ struct termios tios;
+
+ req->handle = -1;
+
+ flags = 0;
+ switch(req->access & (GENERIC_READ | GENERIC_WRITE))
+ {
+ case GENERIC_READ: flags |= O_RDONLY; break;
+ case GENERIC_WRITE: flags |= O_WRONLY; break;
+ case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break;
+ default: break;
+ }
+
+ fd = open( req->name, flags );
+ if(fd < 0)
+ {
+ file_set_error();
+ return;
+ }
+
+ /* check its really a serial port */
+ if(0>tcgetattr(fd,&tios))
+ {
+ file_set_error();
+ close(fd);
+ return;
+ }
+
+ serial = alloc_object( &serial_ops, fd );
+ if (serial)
+ {
+ strncpy(serial->name,req->name,sizeof serial->name);
+ serial->name[sizeof(serial->name)-1] = 0;
+
+ serial->access = req->access;
+ serial->readinterval = 0;
+ serial->readmult = 0;
+ serial->readconst = 0;
+ serial->writemult = 0;
+ serial->writeconst = 0;
+ serial->eventmask = 0;
+ serial->commerror = 0;
+
+ req->handle = alloc_handle( current->process, serial, req->access, req->inherit );
+ release_object( serial );
+ }
+}
+
diff --git a/server/trace.c b/server/trace.c
index 89b0998..07c1a6d 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1417,6 +1417,20 @@
fprintf( stderr, " event=%d", req->event );
}
+static void dump_create_serial_request( const struct create_serial_request *req )
+{
+ fprintf( stderr, " access=%08x,", req->access );
+ fprintf( stderr, " inherit=%d,", req->inherit );
+ fprintf( stderr, " sharing=%08x,", req->sharing );
+ fprintf( stderr, " name=" );
+ dump_string( req, req->name );
+}
+
+static void dump_create_serial_reply( const struct create_serial_request *req )
+{
+ fprintf( stderr, " handle=%d", req->handle );
+}
+
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_wait_process_request,
@@ -1525,6 +1539,7 @@
(dump_func)dump_get_msg_queue_request,
(dump_func)dump_wake_queue_request,
(dump_func)dump_wait_input_idle_request,
+ (dump_func)dump_create_serial_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -1635,6 +1650,7 @@
(dump_func)dump_get_msg_queue_reply,
(dump_func)0,
(dump_func)dump_wait_input_idle_reply,
+ (dump_func)dump_create_serial_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -1745,6 +1761,7 @@
"get_msg_queue",
"wake_queue",
"wait_input_idle",
+ "create_serial",
};
/* ### make_requests end ### */