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.
15 #include <sys/errno.h>
18 #include <sys/types.h>
24 #include "server/thread.h"
28 struct object obj
; /* object header */
29 int fd
; /* Unix file descriptor */
30 int is_read
; /* is this the read or write part? */
33 static void console_dump( struct object
*obj
, int verbose
);
34 static int console_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
35 static void console_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
);
36 static int console_signaled( struct object
*obj
, struct thread
*thread
);
37 static int console_get_read_fd( struct object
*obj
);
38 static int console_get_write_fd( struct object
*obj
);
39 static int console_get_info( struct object
*obj
, struct get_file_info_reply
*reply
);
40 static void console_destroy( struct object
*obj
);
42 static const struct object_ops console_ops
=
56 static const struct select_ops select_ops
=
59 NULL
/* we never set a timeout on a console */
62 int create_console( int fd
, struct object
*obj
[2] )
64 struct console
*console_read
, *console_write
;
65 int read_fd
, write_fd
;
67 if ((read_fd
= (fd
!= -1) ? dup(fd
) : dup(0)) == -1)
72 if ((write_fd
= (fd
!= -1) ? dup(fd
) : dup(0)) == -1)
78 if (!(console_read
= mem_alloc( sizeof(struct console
) )))
84 if (!(console_write
= mem_alloc( sizeof(struct console
) )))
91 init_object( &console_read
->obj
, &console_ops
, NULL
);
92 init_object( &console_write
->obj
, &console_ops
, NULL
);
93 console_read
->fd
= read_fd
;
94 console_read
->is_read
= 1;
95 console_write
->fd
= write_fd
;
96 console_write
->is_read
= 0;
98 obj
[0] = &console_read
->obj
;
99 obj
[1] = &console_write
->obj
;
103 int set_console_fd( int handle
, int fd
)
105 struct console
*console
;
107 if (!(console
= (struct console
*)get_handle_obj( current
->process
, handle
,
110 if ((fd
= dup(fd
)) == -1)
113 release_object( console
);
116 close( console
->fd
);
118 release_object( console
);
122 static void console_dump( struct object
*obj
, int verbose
)
124 struct console
*console
= (struct console
*)obj
;
125 assert( obj
->ops
== &console_ops
);
126 fprintf( stderr
, "Console %s fd=%d\n",
127 console
->is_read
? "input" : "output", console
->fd
);
130 static int console_add_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
132 struct console
*console
= (struct console
*)obj
;
133 assert( obj
->ops
== &console_ops
);
134 if (!obj
->head
) /* first on the queue */
136 if (!add_select_user( console
->fd
,
137 console
->is_read
? READ_EVENT
: WRITE_EVENT
,
138 &select_ops
, console
))
140 SET_ERROR( ERROR_OUTOFMEMORY
);
144 add_queue( obj
, entry
);
148 static void console_remove_queue( struct object
*obj
, struct wait_queue_entry
*entry
)
150 struct console
*console
= (struct console
*)grab_object(obj
);
151 assert( obj
->ops
== &console_ops
);
153 remove_queue( obj
, entry
);
154 if (!obj
->head
) /* last on the queue is gone */
155 remove_select_user( console
->fd
);
156 release_object( obj
);
159 static int console_signaled( struct object
*obj
, struct thread
*thread
)
162 struct timeval tv
= { 0, 0 };
163 struct console
*console
= (struct console
*)obj
;
164 assert( obj
->ops
== &console_ops
);
167 FD_SET( console
->fd
, &fds
);
168 if (console
->is_read
)
169 return select( console
->fd
+ 1, &fds
, NULL
, NULL
, &tv
) > 0;
171 return select( console
->fd
+ 1, NULL
, &fds
, NULL
, &tv
) > 0;
174 static int console_get_read_fd( struct object
*obj
)
176 struct console
*console
= (struct console
*)obj
;
177 assert( obj
->ops
== &console_ops
);
179 if (!console
->is_read
)
181 SET_ERROR( ERROR_ACCESS_DENIED
);
184 return dup( console
->fd
);
187 static int console_get_write_fd( struct object
*obj
)
189 struct console
*console
= (struct console
*)obj
;
190 assert( obj
->ops
== &console_ops
);
192 if (console
->is_read
)
194 SET_ERROR( ERROR_ACCESS_DENIED
);
197 return dup( console
->fd
);
200 static int console_get_info( struct object
*obj
, struct get_file_info_reply
*reply
)
202 memset( reply
, 0, sizeof(*reply
) );
203 reply
->type
= FILE_TYPE_CHAR
;
207 static void console_destroy( struct object
*obj
)
209 struct console
*console
= (struct console
*)obj
;
210 assert( obj
->ops
== &console_ops
);
211 close( console
->fd
);