Tests for VarAdd.
[wine/multimedia.git] / server / named_pipe.c
blobc8358dca01a43d253a18e9411b146295c42a12f0
1 /*
2 * Server-side pipe management
4 * Copyright (C) 1998 Alexandre Julliard
5 * Copyright (C) 2001 Mike McCormack
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * TODO:
22 * message mode
25 #include "config.h"
26 #include "wine/port.h"
28 #include <assert.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/time.h>
35 #include <sys/types.h>
36 #ifdef HAVE_SYS_SOCKET_H
37 #include <sys/socket.h>
38 #endif
39 #include <time.h>
40 #include <unistd.h>
41 #ifdef HAVE_POLL_H
42 #include <poll.h>
43 #endif
45 #include "windef.h"
46 #include "winbase.h"
48 #include "file.h"
49 #include "handle.h"
50 #include "thread.h"
51 #include "request.h"
53 enum pipe_state
55 ps_idle_server,
56 ps_wait_open,
57 ps_connected_server,
58 ps_wait_disconnect,
59 ps_disconnected_server,
60 ps_wait_connect
63 struct named_pipe;
65 struct pipe_server
67 struct object obj; /* object header */
68 struct fd *fd; /* pipe file descriptor */
69 struct list entry; /* entry in named pipe servers list */
70 enum pipe_state state; /* server state */
71 struct pipe_client *client; /* client that this server is connected to */
72 struct named_pipe *pipe;
73 struct timeout_user *flush_poll;
74 struct event *event;
75 struct list wait_q; /* only a single one can be queued */
78 struct pipe_client
80 struct object obj; /* object header */
81 struct fd *fd; /* pipe file descriptor */
82 struct pipe_server *server; /* server that this client is connected to */
85 struct named_pipe
87 struct object obj; /* object header */
88 unsigned int flags;
89 unsigned int maxinstances;
90 unsigned int outsize;
91 unsigned int insize;
92 unsigned int timeout;
93 unsigned int instances;
94 struct list servers; /* list of servers using this pipe */
95 struct list waiters; /* list of clients waiting to connect */
98 static void named_pipe_dump( struct object *obj, int verbose );
99 static void named_pipe_destroy( struct object *obj );
101 static const struct object_ops named_pipe_ops =
103 sizeof(struct named_pipe), /* size */
104 named_pipe_dump, /* dump */
105 no_add_queue, /* add_queue */
106 NULL, /* remove_queue */
107 NULL, /* signaled */
108 NULL, /* satisfied */
109 no_signal, /* signal */
110 no_get_fd, /* get_fd */
111 named_pipe_destroy /* destroy */
114 /* common to clients and servers */
115 static int pipe_end_get_poll_events( struct fd *fd );
116 static int pipe_end_get_info( struct fd *fd );
118 /* server end functions */
119 static void pipe_server_dump( struct object *obj, int verbose );
120 static struct fd *pipe_server_get_fd( struct object *obj );
121 static void pipe_server_destroy( struct object *obj);
122 static int pipe_server_flush( struct fd *fd, struct event **event );
124 static const struct object_ops pipe_server_ops =
126 sizeof(struct pipe_server), /* size */
127 pipe_server_dump, /* dump */
128 default_fd_add_queue, /* add_queue */
129 default_fd_remove_queue, /* remove_queue */
130 default_fd_signaled, /* signaled */
131 no_satisfied, /* satisfied */
132 no_signal, /* signal */
133 pipe_server_get_fd, /* get_fd */
134 pipe_server_destroy /* destroy */
137 static const struct fd_ops pipe_server_fd_ops =
139 pipe_end_get_poll_events, /* get_poll_events */
140 default_poll_event, /* poll_event */
141 pipe_server_flush, /* flush */
142 pipe_end_get_info, /* get_file_info */
143 no_queue_async, /* queue_async */
144 no_cancel_async, /* cancel_async */
147 /* client end functions */
148 static void pipe_client_dump( struct object *obj, int verbose );
149 static struct fd *pipe_client_get_fd( struct object *obj );
150 static void pipe_client_destroy( struct object *obj );
151 static int pipe_client_flush( struct fd *fd, struct event **event );
153 static const struct object_ops pipe_client_ops =
155 sizeof(struct pipe_client), /* size */
156 pipe_client_dump, /* dump */
157 default_fd_add_queue, /* add_queue */
158 default_fd_remove_queue, /* remove_queue */
159 default_fd_signaled, /* signaled */
160 no_satisfied, /* satisfied */
161 no_signal, /* signal */
162 pipe_client_get_fd, /* get_fd */
163 pipe_client_destroy /* destroy */
166 static const struct fd_ops pipe_client_fd_ops =
168 pipe_end_get_poll_events, /* get_poll_events */
169 default_poll_event, /* poll_event */
170 pipe_client_flush, /* flush */
171 pipe_end_get_info, /* get_file_info */
172 no_queue_async, /* queue_async */
173 no_cancel_async /* cancel_async */
176 static void named_pipe_dump( struct object *obj, int verbose )
178 struct named_pipe *pipe = (struct named_pipe *) obj;
179 assert( obj->ops == &named_pipe_ops );
180 fprintf( stderr, "Named pipe " );
181 dump_object_name( &pipe->obj );
182 fprintf( stderr, "\n" );
185 static void pipe_server_dump( struct object *obj, int verbose )
187 struct pipe_server *server = (struct pipe_server *) obj;
188 assert( obj->ops == &pipe_server_ops );
189 fprintf( stderr, "Named pipe server pipe=%p state=%d\n", server->pipe, server->state );
192 static void pipe_client_dump( struct object *obj, int verbose )
194 struct pipe_client *client = (struct pipe_client *) obj;
195 assert( obj->ops == &pipe_client_ops );
196 fprintf( stderr, "Named pipe client server=%p\n", client->server );
199 static void named_pipe_destroy( struct object *obj)
201 struct named_pipe *pipe = (struct named_pipe *) obj;
203 assert( list_empty( &pipe->servers ) );
204 assert( !pipe->instances );
205 async_terminate_queue( &pipe->waiters, STATUS_HANDLES_CLOSED );
208 static struct fd *pipe_client_get_fd( struct object *obj )
210 struct pipe_client *client = (struct pipe_client *) obj;
211 if( client->fd )
212 return (struct fd *) grab_object( client->fd );
213 set_error( STATUS_PIPE_DISCONNECTED );
214 return NULL;
217 static struct fd *pipe_server_get_fd( struct object *obj )
219 struct pipe_server *server = (struct pipe_server *) obj;
221 switch(server->state)
223 case ps_connected_server:
224 case ps_wait_disconnect:
225 assert( server->fd );
226 return (struct fd *) grab_object( server->fd );
228 case ps_wait_open:
229 case ps_idle_server:
230 set_error( STATUS_PIPE_LISTENING );
231 break;
233 case ps_disconnected_server:
234 case ps_wait_connect:
235 set_error( STATUS_PIPE_DISCONNECTED );
236 break;
238 return NULL;
242 static void notify_empty( struct pipe_server *server )
244 if( !server->flush_poll )
245 return;
246 assert( server->state == ps_connected_server );
247 assert( server->event );
248 remove_timeout_user( server->flush_poll );
249 server->flush_poll = NULL;
250 set_event( server->event );
251 release_object( server->event );
252 server->event = NULL;
255 static void do_disconnect( struct pipe_server *server )
257 /* we may only have a server fd, if the client disconnected */
258 if( server->client )
260 assert( server->client->server == server );
261 assert( server->client->fd );
262 release_object( server->client->fd );
263 server->client->fd = NULL;
265 assert( server->fd );
266 release_object( server->fd );
267 server->fd = NULL;
270 static void pipe_server_destroy( struct object *obj)
272 struct pipe_server *server = (struct pipe_server *)obj;
274 assert( obj->ops == &pipe_server_ops );
276 if( server->fd )
278 notify_empty( server );
279 do_disconnect( server );
282 if( server->client )
284 server->client->server = NULL;
285 server->client = NULL;
288 async_terminate_head( &server->wait_q, STATUS_HANDLES_CLOSED );
290 assert( server->pipe->instances );
291 server->pipe->instances--;
293 list_remove( &server->entry );
294 release_object( server->pipe );
297 static void pipe_client_destroy( struct object *obj)
299 struct pipe_client *client = (struct pipe_client *)obj;
300 struct pipe_server *server = client->server;
302 assert( obj->ops == &pipe_client_ops );
304 if( server )
306 notify_empty( server );
308 switch( server->state )
310 case ps_connected_server:
311 /* Don't destroy the server's fd here as we can't
312 do a successful flush without it. */
313 server->state = ps_wait_disconnect;
314 release_object( client->fd );
315 client->fd = NULL;
316 break;
317 case ps_disconnected_server:
318 server->state = ps_wait_connect;
319 break;
320 case ps_idle_server:
321 case ps_wait_open:
322 case ps_wait_disconnect:
323 case ps_wait_connect:
324 assert( 0 );
326 assert( server->client );
327 server->client = NULL;
328 client->server = NULL;
330 assert( !client->fd );
333 static int pipe_end_get_poll_events( struct fd *fd )
335 return POLLIN | POLLOUT; /* FIXME */
338 static int pipe_data_remaining( struct pipe_server *server )
340 struct pollfd pfd;
341 int fd;
343 assert( server->client );
345 fd = get_unix_fd( server->client->fd );
346 if( fd < 0 )
347 return 0;
348 pfd.fd = fd;
349 pfd.events = POLLIN;
350 pfd.revents = 0;
352 if( 0 > poll( &pfd, 1, 0 ) )
353 return 0;
355 return pfd.revents&POLLIN;
358 static void check_flushed( void *arg )
360 struct pipe_server *server = (struct pipe_server*) arg;
362 assert( server->event );
363 if( pipe_data_remaining( server ) )
365 struct timeval tv;
367 gettimeofday( &tv, NULL );
368 add_timeout( &tv, 100 );
369 server->flush_poll = add_timeout_user( &tv, check_flushed, server );
371 else
373 /* notify_empty( server ); */
374 server->flush_poll = NULL;
375 set_event( server->event );
376 release_object( server->event );
377 server->event = NULL;
381 static int pipe_server_flush( struct fd *fd, struct event **event )
383 struct pipe_server *server = get_fd_user( fd );
385 if( !server )
386 return 0;
388 if( server->state != ps_connected_server )
389 return 0;
391 /* FIXME: if multiple threads flush the same pipe,
392 maybe should create a list of processes to notify */
393 if( server->flush_poll )
394 return 0;
396 if( pipe_data_remaining( server ) )
398 struct timeval tv;
400 /* this kind of sux -
401 there's no unix way to be alerted when a pipe becomes empty */
402 server->event = create_event( NULL, 0, 0, 0 );
403 if( !server->event )
404 return 0;
405 gettimeofday( &tv, NULL );
406 add_timeout( &tv, 100 );
407 server->flush_poll = add_timeout_user( &tv, check_flushed, server );
408 *event = server->event;
411 return 0;
414 static int pipe_client_flush( struct fd *fd, struct event **event )
416 /* FIXME: what do we have to do for this? */
417 return 0;
420 static int pipe_end_get_info( struct fd *fd )
422 return 0;
425 static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len )
427 struct named_pipe *pipe;
429 pipe = create_named_object( sync_namespace, &named_pipe_ops, name, len );
430 if( pipe )
432 if( get_error() != STATUS_OBJECT_NAME_COLLISION )
434 /* initialize it if it didn't already exist */
435 pipe->instances = 0;
436 list_init( &pipe->servers );
437 list_init( &pipe->waiters );
440 return pipe;
443 static struct named_pipe *open_named_pipe( const WCHAR *name, size_t len )
445 struct object *obj;
447 if ((obj = find_object( sync_namespace, name, len )))
449 if (obj->ops == &named_pipe_ops) return (struct named_pipe *)obj;
450 release_object( obj );
451 set_error( STATUS_OBJECT_TYPE_MISMATCH );
453 else set_error( STATUS_OBJECT_NAME_NOT_FOUND );
455 return NULL;
458 static struct pipe_server *get_pipe_server_obj( struct process *process,
459 obj_handle_t handle, unsigned int access )
461 struct object *obj;
462 obj = get_handle_obj( process, handle, access, &pipe_server_ops );
463 return (struct pipe_server *) obj;
466 static struct pipe_server *create_pipe_server( struct named_pipe *pipe )
468 struct pipe_server *server;
470 server = alloc_object( &pipe_server_ops );
471 if( !server )
472 return NULL;
474 server->fd = NULL;
475 server->pipe = pipe;
476 server->state = ps_idle_server;
477 server->client = NULL;
478 server->flush_poll = NULL;
479 list_init( &server->wait_q );
481 list_add_head( &pipe->servers, &server->entry );
482 grab_object( pipe );
484 return server;
487 static struct pipe_client *create_pipe_client( struct pipe_server *server )
489 struct pipe_client *client;
491 client = alloc_object( &pipe_client_ops );
492 if( !client )
493 return NULL;
495 client->fd = NULL;
496 client->server = server;
498 return client;
501 static inline struct pipe_server *find_server( struct named_pipe *pipe, enum pipe_state state )
503 struct pipe_server *server;
505 LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
507 if (server->state == state) return (struct pipe_server *)grab_object( server );
509 return NULL;
512 static inline struct pipe_server *find_server2( struct named_pipe *pipe,
513 enum pipe_state state1, enum pipe_state state2 )
515 struct pipe_server *server;
517 LIST_FOR_EACH_ENTRY( server, &pipe->servers, struct pipe_server, entry )
519 if (server->state == state1 || server->state == state2)
520 return (struct pipe_server *)grab_object( server );
522 return NULL;
525 DECL_HANDLER(create_named_pipe)
527 struct named_pipe *pipe;
528 struct pipe_server *server;
530 reply->handle = 0;
531 pipe = create_named_pipe( get_req_data(), get_req_data_size() );
532 if( !pipe )
533 return;
535 if( get_error() != STATUS_OBJECT_NAME_COLLISION )
537 pipe->insize = req->insize;
538 pipe->outsize = req->outsize;
539 pipe->maxinstances = req->maxinstances;
540 pipe->timeout = req->timeout;
541 pipe->flags = req->flags;
543 else
545 set_error( 0 ); /* clear the name collision */
546 if( pipe->maxinstances <= pipe->instances )
548 set_error( STATUS_PIPE_BUSY );
549 release_object( pipe );
550 return;
552 if( ( pipe->maxinstances != req->maxinstances ) ||
553 ( pipe->timeout != req->timeout ) ||
554 ( pipe->flags != req->flags ) )
556 set_error( STATUS_ACCESS_DENIED );
557 release_object( pipe );
558 return;
562 server = create_pipe_server( pipe );
563 if(server)
565 reply->handle = alloc_handle( current->process, server,
566 GENERIC_READ|GENERIC_WRITE, req->inherit );
567 server->pipe->instances++;
568 release_object( server );
571 release_object( pipe );
574 DECL_HANDLER(open_named_pipe)
576 struct pipe_server *server;
577 struct pipe_client *client;
578 struct named_pipe *pipe;
579 int fds[2];
581 pipe = open_named_pipe( get_req_data(), get_req_data_size() );
582 if ( !pipe )
584 set_error( STATUS_NO_SUCH_FILE );
585 return;
588 server = find_server2( pipe, ps_idle_server, ps_wait_open );
589 release_object( pipe );
591 if ( !server )
593 set_error( STATUS_PIPE_NOT_AVAILABLE );
594 return;
597 client = create_pipe_client( server );
598 if( client )
600 if( !socketpair( PF_UNIX, SOCK_STREAM, 0, fds ) )
602 assert( !client->fd );
603 assert( !server->fd );
604 client->fd = create_anonymous_fd( &pipe_client_fd_ops,
605 fds[1], &client->obj );
606 server->fd = create_anonymous_fd( &pipe_server_fd_ops,
607 fds[0], &server->obj );
608 if (client->fd && server->fd)
610 if( server->state == ps_wait_open )
611 async_terminate_head( &server->wait_q, STATUS_SUCCESS );
612 assert( list_empty( &server->wait_q ) );
613 server->state = ps_connected_server;
614 server->client = client;
615 client->server = server;
616 reply->handle = alloc_handle( current->process, client,
617 req->access, req->inherit );
620 else
621 file_set_error();
623 release_object( client );
625 release_object( server );
628 DECL_HANDLER(connect_named_pipe)
630 struct pipe_server *server;
632 server = get_pipe_server_obj(current->process, req->handle, 0);
633 if(!server)
634 return;
636 switch( server->state )
638 case ps_idle_server:
639 case ps_wait_connect:
640 assert( !server->fd );
641 server->state = ps_wait_open;
642 create_async( current, NULL, &server->wait_q,
643 req->func, req->overlapped, NULL );
644 async_terminate_queue( &server->pipe->waiters, STATUS_SUCCESS );
645 break;
646 case ps_connected_server:
647 assert( server->fd );
648 set_error( STATUS_PIPE_CONNECTED );
649 break;
650 case ps_disconnected_server:
651 set_error( STATUS_PIPE_BUSY );
652 break;
653 case ps_wait_disconnect:
654 set_error( STATUS_NO_DATA_DETECTED );
655 break;
656 case ps_wait_open:
657 set_error( STATUS_INVALID_HANDLE );
658 break;
661 release_object(server);
664 DECL_HANDLER(wait_named_pipe)
666 struct named_pipe *pipe;
667 struct pipe_server *server;
669 if (!(pipe = open_named_pipe( get_req_data(), get_req_data_size() )))
671 set_error( STATUS_PIPE_NOT_AVAILABLE );
672 return;
674 server = find_server( pipe, ps_wait_open );
675 if( server )
677 /* there's already a server waiting for a client to connect */
678 thread_queue_apc( current, NULL, req->func, APC_ASYNC_IO,
679 1, req->overlapped, NULL, (void *)STATUS_SUCCESS );
680 release_object( server );
682 else
684 unsigned int timeout;
685 if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT)
686 timeout = pipe->timeout;
687 else
688 timeout = req->timeout;
690 if (req->timeout == NMPWAIT_WAIT_FOREVER)
691 create_async( current, NULL, &pipe->waiters,
692 req->func, req->overlapped, NULL );
693 else
694 create_async( current, &timeout, &pipe->waiters,
695 req->func, req->overlapped, NULL );
698 release_object( pipe );
701 DECL_HANDLER(disconnect_named_pipe)
703 struct pipe_server *server;
705 reply->fd = -1;
706 server = get_pipe_server_obj( current->process, req->handle, 0 );
707 if( !server )
708 return;
709 switch( server->state )
711 case ps_connected_server:
712 assert( server->fd );
713 assert( server->client );
714 assert( server->client->fd );
716 notify_empty( server );
718 /* Dump the client and server fds, but keep the pointers
719 around - client loses all waiting data */
720 server->state = ps_disconnected_server;
721 do_disconnect( server );
722 reply->fd = flush_cached_fd( current->process, req->handle );
723 break;
725 case ps_wait_disconnect:
726 assert( !server->client );
727 assert( server->fd );
728 do_disconnect( server );
729 server->state = ps_wait_connect;
730 reply->fd = flush_cached_fd( current->process, req->handle );
731 break;
733 case ps_idle_server:
734 case ps_wait_open:
735 case ps_disconnected_server:
736 case ps_wait_connect:
737 set_error( STATUS_PIPE_DISCONNECTED );
738 break;
740 release_object( server );
743 DECL_HANDLER(get_named_pipe_info)
745 struct pipe_server *server;
747 server = get_pipe_server_obj( current->process, req->handle, 0 );
748 if(!server)
749 return;
751 reply->flags = server->pipe->flags;
752 reply->maxinstances = server->pipe->maxinstances;
753 reply->insize = server->pipe->insize;
754 reply->outsize = server->pipe->outsize;
756 release_object(server);