2 * Server-side console management
4 * Copyright (C) 1998 Alexandre Julliard
6 * FIXME: all this stuff is a hack to avoid breaking
7 * the client-side console support.
14 #include <sys/errno.h>
17 #include <sys/types.h>
23 #include "server/thread.h"
27 struct object obj
; /* object header */
28 int fd
; /* Unix file descriptor */
29 int is_read
; /* is this the read or write part? */
32 static void console_dump( struct object
*obj
, int verbose
);
33 static int console_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
34 static void console_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
35 static int console_signaled( struct object
*obj
, struct thread
*thread
);
36 static int console_get_read_fd( struct object
*obj
);
37 static int console_get_write_fd( struct object
*obj
);
38 static void console_destroy( struct object
*obj
);
40 static const struct object_ops console_ops
=
53 static const struct select_ops select_ops
=
56 NULL
/* we never set a timeout on a console */
59 int create_console( int fd
, struct object
*obj
[2] )
61 struct console
*console_read
, *console_write
;
62 int read_fd
, write_fd
;
64 if ((read_fd
= (fd
!= -1) ? dup(fd
) : dup(0)) == -1)
69 if ((write_fd
= (fd
!= -1) ? dup(fd
) : dup(0)) == -1)
75 if (!(console_read
= mem_alloc( sizeof(struct console
) )))
81 if (!(console_write
= mem_alloc( sizeof(struct console
) )))
88 init_object( &console_read
->obj
, &console_ops
, NULL
);
89 init_object( &console_write
->obj
, &console_ops
, NULL
);
90 console_read
->fd
= read_fd
;
91 console_read
->is_read
= 1;
92 console_write
->fd
= write_fd
;
93 console_write
->is_read
= 0;
95 obj
[0] = &console_read
->obj
;
96 obj
[1] = &console_write
->obj
;
100 int set_console_fd( int handle
, int fd
)
102 struct console
*console
;
104 if (!(console
= (struct console
*)get_handle_obj( current
->process
, handle
,
107 if ((fd
= dup(fd
)) == -1)
110 release_object( console
);
113 close( console
->fd
);
115 release_object( console
);
119 static void console_dump( struct object
*obj
, int verbose
)
121 struct console
*console
= (struct console
*)obj
;
122 assert( obj
->ops
== &console_ops
);
123 printf( "Console %s fd=%d\n",
124 console
->is_read
? "input" : "output", console
->fd
);
127 static int console_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
129 struct console
*console
= (struct console
*)obj
;
130 assert( obj
->ops
== &console_ops
);
131 if (!obj
->head
) /* first on the queue */
133 if (!add_select_user( console
->fd
,
134 console
->is_read
? READ_EVENT
: WRITE_EVENT
,
135 &select_ops
, console
))
137 SET_ERROR( ERROR_OUTOFMEMORY
);
141 add_queue( obj
, entry
);
145 static void console_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
147 struct console
*console
= (struct console
*)grab_object(obj
);
148 assert( obj
->ops
== &console_ops
);
150 remove_queue( obj
, entry
);
151 if (!obj
->head
) /* last on the queue is gone */
152 remove_select_user( console
->fd
);
153 release_object( obj
);
156 static int console_signaled( struct object
*obj
, struct thread
*thread
)
159 struct timeval tv
= { 0, 0 };
160 struct console
*console
= (struct console
*)obj
;
161 assert( obj
->ops
== &console_ops
);
164 FD_SET( console
->fd
, &fds
);
165 if (console
->is_read
)
166 return select( console
->fd
+ 1, &fds
, NULL
, NULL
, &tv
) > 0;
168 return select( console
->fd
+ 1, NULL
, &fds
, NULL
, &tv
) > 0;
171 static int console_get_read_fd( struct object
*obj
)
173 struct console
*console
= (struct console
*)obj
;
174 assert( obj
->ops
== &console_ops
);
176 if (!console
->is_read
)
178 SET_ERROR( ERROR_ACCESS_DENIED
);
181 return dup( console
->fd
);
184 static int console_get_write_fd( struct object
*obj
)
186 struct console
*console
= (struct console
*)obj
;
187 assert( obj
->ops
== &console_ops
);
189 if (console
->is_read
)
191 SET_ERROR( ERROR_ACCESS_DENIED
);
194 return dup( console
->fd
);
197 static void console_destroy( struct object
*obj
)
199 struct console
*console
= (struct console
*)obj
;
200 assert( obj
->ops
== &console_ops
);
201 close( console
->fd
);