Added serial port object to the server.
[wine] / server / serial.c
1 /*
2  * Server-side serial port communications management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  * Copyright (C) 2000 Mike McCormack
6  *
7  * TODO:
8  *  Add async read, write and WaitCommEvent handling.
9  *
10  */
11
12 #include "config.h"
13
14 #include <assert.h>
15 #include <fcntl.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <errno.h>
20 #ifdef HAVE_SYS_ERRNO_H
21 #include <sys/errno.h>
22 #endif
23 #include <sys/stat.h>
24 #include <sys/time.h>
25 #include <sys/types.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include <utime.h>
29 #include <termios.h>
30 #include <sys/ioctl.h>
31
32 #include "winerror.h"
33 #include "winbase.h"
34
35 #include "handle.h"
36 #include "thread.h"
37 #include "request.h"
38
39 static void serial_dump( struct object *obj, int verbose );
40 static void serial_destroy( struct object *obj );
41 static int serial_get_read_fd( struct object *obj );
42 static int serial_get_write_fd( struct object *obj );
43 static int serial_get_info( struct object *obj, struct get_file_info_request *req );
44 static int serial_get_poll_events( struct object *obj );
45
46 struct serial
47 {
48     struct object       obj;
49     char                name[16]; /* eg. /dev/ttyS1 */
50     int                 access;
51
52     /* timeout values */
53     unsigned int        readinterval;
54     unsigned int        readconst;
55     unsigned int        readmult;
56     unsigned int        writeconst;
57     unsigned int        writemult;
58
59     unsigned int        eventmask;
60     unsigned int        commerror;
61
62     struct termios      original;
63
64     /* FIXME: add dcb, comm status, handler module, sharing */
65 };
66
67 static const struct object_ops serial_ops =
68 {
69     sizeof(struct serial),        /* size */
70     serial_dump,                  /* dump */
71     default_poll_add_queue,       /* add_queue */
72     default_poll_remove_queue,    /* remove_queue */
73     default_poll_signaled,        /* signaled */
74     no_satisfied,                 /* satisfied */
75     serial_get_poll_events,       /* get_poll_events */
76     default_poll_event,           /* poll_event */
77     serial_get_read_fd,           /* get_read_fd */
78     serial_get_write_fd,          /* get_write_fd */
79     no_flush,                     /* flush */
80     serial_get_info,              /* get_file_info */
81     serial_destroy                /* destroy */
82 };
83
84 /* SERIAL PORT functions */
85
86 static void serial_dump( struct object *obj, int verbose )
87 {
88     struct serial *serial = (struct serial *)obj;
89     assert( obj->ops == &serial_ops );
90
91     fprintf( stderr, "Port fd=%d name='%s' mask=%x\n", 
92              serial->obj.fd, serial->name,serial->eventmask);
93 }
94
95 /* same as file_destroy, but don't delete comm ports */
96 static void serial_destroy( struct object *obj )
97 {
98     assert( obj->ops == &serial_ops );
99 }
100
101 struct serial *get_serial_obj( struct process *process, int handle, unsigned int access )
102 {
103     return (struct serial *)get_handle_obj( process, handle, access, &serial_ops );
104 }
105
106 static int serial_get_poll_events( struct object *obj )
107 {
108     struct serial *serial = (struct serial *)obj;
109     int events = 0;
110     assert( obj->ops == &serial_ops );
111     if (serial->access & GENERIC_READ) events |= POLLIN;
112     if (serial->access & GENERIC_WRITE) events |= POLLOUT;
113     return events;
114 }
115
116 static int serial_get_read_fd( struct object *obj )
117 {
118     struct serial *serial = (struct serial *)obj;
119     assert( obj->ops == &serial_ops );
120     return dup( serial->obj.fd );
121 }
122
123 static int serial_get_write_fd( struct object *obj )
124 {
125     struct serial *serial = (struct serial *)obj;
126     assert( obj->ops == &serial_ops );
127     return dup( serial->obj.fd );
128 }
129
130 static int serial_get_info( struct object *obj, struct get_file_info_request *req )
131 {
132     assert( obj->ops == &serial_ops );
133     req->type        = FILE_TYPE_CHAR;
134     req->attr        = 0;
135     req->access_time = 0;
136     req->write_time  = 0;
137     req->size_high   = 0;
138     req->size_low    = 0;
139     req->links       = 0;
140     req->index_high  = 0;
141     req->index_low   = 0;
142     req->serial      = 0;
143     return 1;
144 }
145
146 /* create a serial */
147 DECL_HANDLER(create_serial)
148 {
149     struct serial *serial;
150     int fd,flags;
151     struct termios tios;
152
153     req->handle = -1;
154
155     flags = 0;
156     switch(req->access & (GENERIC_READ | GENERIC_WRITE))
157     {
158     case GENERIC_READ:  flags |= O_RDONLY; break;
159     case GENERIC_WRITE: flags |= O_WRONLY; break;
160     case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break;
161     default: break;
162     }
163
164     fd = open( req->name, flags );
165     if(fd < 0)
166     {
167         file_set_error();
168         return;
169     }
170
171     /* check its really a serial port */
172     if(0>tcgetattr(fd,&tios))
173     {
174         file_set_error();
175         close(fd);
176         return;
177     }
178
179     serial = alloc_object( &serial_ops, fd );
180     if (serial)
181     {
182         strncpy(serial->name,req->name,sizeof serial->name);
183         serial->name[sizeof(serial->name)-1] = 0;
184
185         serial->access       = req->access;
186         serial->readinterval = 0;
187         serial->readmult     = 0;
188         serial->readconst    = 0;
189         serial->writemult    = 0;
190         serial->writeconst   = 0;
191         serial->eventmask    = 0;
192         serial->commerror    = 0;
193
194         req->handle = alloc_handle( current->process, serial, req->access, req->inherit );
195         release_object( serial );
196     }
197 }
198