Added beginnings of server-side file handling.
[wine/multimedia.git] / server / file.c
blob82319f329a6f5fa55cabb20aae22ed33d4681c34
1 /*
2 * Server-side file management
4 * Copyright (C) 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <fcntl.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/errno.h>
12 #include <sys/stat.h>
13 #include <sys/time.h>
14 #include <sys/types.h>
15 #include <time.h>
16 #include <unistd.h>
18 #include "winerror.h"
19 #include "winnt.h"
20 #include "server/thread.h"
22 struct file
24 struct object obj; /* object header */
25 int fd; /* Unix file descriptor */
26 int event; /* possible events on this file */
29 static void file_dump( struct object *obj, int verbose );
30 static void file_add_queue( struct object *obj, struct wait_queue_entry *entry );
31 static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry );
32 static int file_signaled( struct object *obj, struct thread *thread );
33 static int file_satisfied( struct object *obj, struct thread *thread );
34 static void file_destroy( struct object *obj );
36 static const struct object_ops file_ops =
38 file_dump,
39 file_add_queue,
40 file_remove_queue,
41 file_signaled,
42 file_satisfied,
43 file_destroy
46 static void file_event( int fd, int event, void *private );
47 static void file_timeout( int fd, void *private );
49 static const struct select_ops select_ops =
51 file_event,
52 file_timeout
55 struct object *create_file( int fd )
57 struct file *file;
58 int flags;
60 if ((flags = fcntl( fd, F_GETFL )) == -1)
62 perror( "fcntl" );
63 return NULL;
65 if (!(file = mem_alloc( sizeof(*file) ))) return NULL;
66 init_object( &file->obj, &file_ops, NULL );
67 file->fd = fd;
68 switch(flags & 3)
70 case O_RDONLY:
71 file->event = READ_EVENT;
72 break;
73 case O_WRONLY:
74 file->event = WRITE_EVENT;
75 break;
76 case O_RDWR:
77 file->event = READ_EVENT | WRITE_EVENT;
78 break;
80 CLEAR_ERROR();
81 return &file->obj;
84 static void file_dump( struct object *obj, int verbose )
86 struct file *file = (struct file *)obj;
87 assert( obj->ops == &file_ops );
88 printf( "File fd=%d\n", file->fd );
91 static void file_add_queue( struct object *obj, struct wait_queue_entry *entry )
93 struct file *file = (struct file *)obj;
94 assert( obj->ops == &file_ops );
95 if (!obj->head) /* first on the queue */
96 add_select_user( file->fd, READ_EVENT | WRITE_EVENT, &select_ops, file );
97 add_queue( obj, entry );
100 static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry )
102 struct file *file = (struct file *)grab_object(obj);
103 assert( obj->ops == &file_ops );
105 remove_queue( obj, entry );
106 if (!obj->head) /* last on the queue is gone */
107 remove_select_user( file->fd );
108 release_object( obj );
111 static int file_signaled( struct object *obj, struct thread *thread )
113 fd_set read_fds, write_fds;
114 struct timeval tv = { 0, 0 };
116 struct file *file = (struct file *)obj;
117 assert( obj->ops == &file_ops );
119 FD_ZERO( &read_fds );
120 FD_ZERO( &write_fds );
121 if (file->event & READ_EVENT) FD_SET( file->fd, &read_fds );
122 if (file->event & WRITE_EVENT) FD_SET( file->fd, &write_fds );
123 return select( file->fd + 1, &read_fds, &write_fds, NULL, &tv ) > 0;
126 static int file_satisfied( struct object *obj, struct thread *thread )
128 /* Nothing to do */
129 return 0; /* Not abandoned */
132 static void file_destroy( struct object *obj )
134 struct file *file = (struct file *)obj;
135 assert( obj->ops == &file_ops );
136 close( file->fd );
137 free( file );
140 static void file_event( int fd, int event, void *private )
142 struct file *file = (struct file *)private;
143 assert( file );
145 wake_up( &file->obj, 0 );
148 static void file_timeout( int fd, void *private )
150 /* we never set a timeout on a file */
151 assert( 0 );
154 int file_get_unix_handle( int handle, unsigned int access )
156 struct file *file;
157 int unix_handle;
159 if (!(file = (struct file *)get_handle_obj( current->process, handle,
160 access, &file_ops )))
161 return -1;
162 unix_handle = dup( file->fd );
163 release_object( file );
164 return unix_handle;
167 int get_file_info( int handle, struct get_file_info_reply *reply )
169 struct file *file;
170 struct stat st;
172 if (!(file = (struct file *)get_handle_obj( current->process, handle,
173 0, &file_ops )))
174 return 0;
175 if (fstat( file->fd, &st ) == -1)
177 /* file_set_error(); */
178 release_object( file );
179 return 0;
181 if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
182 else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
183 if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
184 reply->access_time = st.st_atime;
185 reply->write_time = st.st_mtime;
186 reply->size_high = 0;
187 reply->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size;
188 reply->links = st.st_nlink;
189 reply->index_high = st.st_dev;
190 reply->index_low = st.st_ino;
191 reply->serial = 0; /* FIXME */
193 release_object( file );
194 return 1;