Rearrange winver detection code and cache the winver value we
[wine.git] / server / file.c
blob041c67c1bf9fe0b3c0084449a6eac6a3e970e54c
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 <string.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <sys/errno.h>
14 #include <sys/stat.h>
15 #include <sys/time.h>
16 #include <sys/types.h>
17 #include <time.h>
18 #include <unistd.h>
19 #include <utime.h>
21 #include "winerror.h"
22 #include "winbase.h"
24 #include "handle.h"
25 #include "thread.h"
27 struct file
29 struct object obj; /* object header */
30 struct select_user select; /* select user */
31 struct file *next; /* next file in hashing list */
32 char *name; /* file name */
33 unsigned int access; /* file access (GENERIC_READ/WRITE) */
34 unsigned int flags; /* flags (FILE_FLAG_*) */
35 unsigned int sharing; /* file sharing mode */
38 #define NAME_HASH_SIZE 37
40 static struct file *file_hash[NAME_HASH_SIZE];
42 static void file_dump( struct object *obj, int verbose );
43 static int file_add_queue( struct object *obj, struct wait_queue_entry *entry );
44 static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry );
45 static int file_signaled( struct object *obj, struct thread *thread );
46 static int file_get_read_fd( struct object *obj );
47 static int file_get_write_fd( struct object *obj );
48 static int file_flush( struct object *obj );
49 static int file_get_info( struct object *obj, struct get_file_info_reply *reply );
50 static void file_destroy( struct object *obj );
52 static const struct object_ops file_ops =
54 file_dump,
55 file_add_queue,
56 file_remove_queue,
57 file_signaled,
58 no_satisfied,
59 file_get_read_fd,
60 file_get_write_fd,
61 file_flush,
62 file_get_info,
63 file_destroy
67 static int get_name_hash( const char *name )
69 int hash = 0;
70 while (*name) hash ^= *name++;
71 return hash % NAME_HASH_SIZE;
74 /* check if the desired access is possible without violating */
75 /* the sharing mode of other opens of the same file */
76 static int check_sharing( const char *name, int hash, unsigned int access,
77 unsigned int sharing )
79 struct file *file;
80 unsigned int existing_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
81 unsigned int existing_access = 0;
83 for (file = file_hash[hash]; file; file = file->next)
85 if (strcmp( file->name, name )) continue;
86 existing_sharing &= file->sharing;
87 existing_access |= file->access;
89 if ((access & GENERIC_READ) && !(existing_sharing & FILE_SHARE_READ)) return 0;
90 if ((access & GENERIC_WRITE) && !(existing_sharing & FILE_SHARE_WRITE)) return 0;
91 if ((existing_access & GENERIC_READ) && !(sharing & FILE_SHARE_READ)) return 0;
92 if ((existing_access & GENERIC_WRITE) && !(sharing & FILE_SHARE_WRITE)) return 0;
93 return 1;
96 static struct object *create_file( int fd, const char *name, unsigned int access,
97 unsigned int sharing, int create, unsigned int attrs )
99 struct file *file;
100 int hash = 0;
102 if (fd == -1)
104 int flags;
105 struct stat st;
107 if (!name)
109 SET_ERROR( ERROR_INVALID_PARAMETER );
110 return NULL;
113 /* check sharing mode */
114 hash = get_name_hash( name );
115 if (!check_sharing( name, hash, access, sharing ))
117 SET_ERROR( ERROR_SHARING_VIOLATION );
118 return NULL;
121 switch(create)
123 case CREATE_NEW: flags = O_CREAT | O_EXCL; break;
124 case CREATE_ALWAYS: flags = O_CREAT | O_TRUNC; break;
125 case OPEN_ALWAYS: flags = O_CREAT; break;
126 case TRUNCATE_EXISTING: flags = O_TRUNC; break;
127 case OPEN_EXISTING: flags = 0; break;
128 default: SET_ERROR( ERROR_INVALID_PARAMETER ); return NULL;
130 switch(access & (GENERIC_READ | GENERIC_WRITE))
132 case 0: break;
133 case GENERIC_READ: flags |= O_RDONLY; break;
134 case GENERIC_WRITE: flags |= O_WRONLY; break;
135 case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break;
138 /* FIXME: should set error to ERROR_ALREADY_EXISTS if file existed before */
139 if ((fd = open( name, flags | O_NONBLOCK,
140 (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666 )) == -1)
142 file_set_error();
143 return NULL;
145 /* Refuse to open a directory */
146 if (fstat( fd, &st ) == -1)
148 file_set_error();
149 close( fd );
150 return NULL;
152 if (S_ISDIR(st.st_mode))
154 SET_ERROR( ERROR_ACCESS_DENIED );
155 close( fd );
156 return NULL;
159 else
161 if ((fd = dup(fd)) == -1)
163 file_set_error();
164 return NULL;
168 if (!(file = mem_alloc( sizeof(*file) )))
170 close( fd );
171 return NULL;
173 if (name)
175 if (!(file->name = mem_alloc( strlen(name) + 1 )))
177 close( fd );
178 free( file );
179 return NULL;
181 strcpy( file->name, name );
182 file->next = file_hash[hash];
183 file_hash[hash] = file;
185 else
187 file->name = NULL;
188 file->next = NULL;
190 init_object( &file->obj, &file_ops, NULL );
191 file->select.fd = fd;
192 file->select.func = default_select_event;
193 file->select.private = file;
194 file->access = access;
195 file->flags = attrs;
196 file->sharing = sharing;
197 register_select_user( &file->select );
198 CLEAR_ERROR();
199 return &file->obj;
202 /* Create a temp file for anonymous mappings */
203 struct file *create_temp_file( int access )
205 struct file *file;
206 char *name;
207 int fd;
211 if (!(name = tmpnam(NULL)))
213 SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );
214 return NULL;
216 fd = open( name, O_CREAT | O_EXCL | O_RDWR, 0600 );
217 } while ((fd == -1) && (errno == EEXIST));
218 if (fd == -1)
220 file_set_error();
221 return NULL;
223 unlink( name );
225 if (!(file = mem_alloc( sizeof(*file) )))
227 close( fd );
228 return NULL;
230 init_object( &file->obj, &file_ops, NULL );
231 file->name = NULL;
232 file->next = NULL;
233 file->select.fd = fd;
234 file->select.func = default_select_event;
235 file->select.private = file;
236 file->access = access;
237 file->flags = 0;
238 file->sharing = 0;
239 register_select_user( &file->select );
240 CLEAR_ERROR();
241 return file;
244 static void file_dump( struct object *obj, int verbose )
246 struct file *file = (struct file *)obj;
247 assert( obj->ops == &file_ops );
248 printf( "File fd=%d flags=%08x name='%s'\n",
249 file->select.fd, file->flags, file->name );
252 static int file_add_queue( struct object *obj, struct wait_queue_entry *entry )
254 struct file *file = (struct file *)obj;
255 assert( obj->ops == &file_ops );
256 if (!obj->head) /* first on the queue */
258 int events = 0;
259 if (file->access & GENERIC_READ) events |= READ_EVENT;
260 if (file->access & GENERIC_WRITE) events |= WRITE_EVENT;
261 set_select_events( &file->select, events );
263 add_queue( obj, entry );
264 return 1;
267 static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry )
269 struct file *file = (struct file *)grab_object(obj);
270 assert( obj->ops == &file_ops );
272 remove_queue( obj, entry );
273 if (!obj->head) /* last on the queue is gone */
274 set_select_events( &file->select, 0 );
275 release_object( obj );
278 static int file_signaled( struct object *obj, struct thread *thread )
280 int events = 0;
281 struct file *file = (struct file *)obj;
282 assert( obj->ops == &file_ops );
284 if (file->access & GENERIC_READ) events |= READ_EVENT;
285 if (file->access & GENERIC_WRITE) events |= WRITE_EVENT;
286 if (check_select_events( &file->select, events ))
288 /* stop waiting on select() if we are signaled */
289 set_select_events( &file->select, 0 );
290 return 1;
292 else
294 /* restart waiting on select() if we are no longer signaled */
295 if (obj->head) set_select_events( &file->select, events );
296 return 0;
300 static int file_get_read_fd( struct object *obj )
302 struct file *file = (struct file *)obj;
303 assert( obj->ops == &file_ops );
304 return dup( file->select.fd );
307 static int file_get_write_fd( struct object *obj )
309 struct file *file = (struct file *)obj;
310 assert( obj->ops == &file_ops );
311 return dup( file->select.fd );
314 static int file_flush( struct object *obj )
316 int ret;
317 struct file *file = (struct file *)grab_object(obj);
318 assert( obj->ops == &file_ops );
320 ret = (fsync( file->select.fd ) != -1);
321 if (!ret) file_set_error();
322 release_object( file );
323 return ret;
326 static int file_get_info( struct object *obj, struct get_file_info_reply *reply )
328 struct stat st;
329 struct file *file = (struct file *)obj;
330 assert( obj->ops == &file_ops );
332 if (fstat( file->select.fd, &st ) == -1)
334 file_set_error();
335 return 0;
337 if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
338 S_ISSOCK(st.st_mode) || isatty(file->select.fd)) reply->type = FILE_TYPE_CHAR;
339 else reply->type = FILE_TYPE_DISK;
340 if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY;
341 else reply->attr = FILE_ATTRIBUTE_ARCHIVE;
342 if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY;
343 reply->access_time = st.st_atime;
344 reply->write_time = st.st_mtime;
345 reply->size_high = 0;
346 reply->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size;
347 reply->links = st.st_nlink;
348 reply->index_high = st.st_dev;
349 reply->index_low = st.st_ino;
350 reply->serial = 0; /* FIXME */
351 return 1;
354 static void file_destroy( struct object *obj )
356 struct file *file = (struct file *)obj;
357 assert( obj->ops == &file_ops );
359 if (file->name)
361 /* remove it from the hashing list */
362 struct file **pptr = &file_hash[get_name_hash( file->name )];
363 while (*pptr && *pptr != file) pptr = &(*pptr)->next;
364 assert( *pptr );
365 *pptr = (*pptr)->next;
366 if (file->flags & FILE_FLAG_DELETE_ON_CLOSE) unlink( file->name );
367 free( file->name );
369 unregister_select_user( &file->select );
370 close( file->select.fd );
371 free( file );
374 /* set the last error depending on errno */
375 void file_set_error(void)
377 switch (errno)
379 case EAGAIN: SET_ERROR( ERROR_SHARING_VIOLATION ); break;
380 case EBADF: SET_ERROR( ERROR_INVALID_HANDLE ); break;
381 case ENOSPC: SET_ERROR( ERROR_HANDLE_DISK_FULL ); break;
382 case EACCES:
383 case EPERM: SET_ERROR( ERROR_ACCESS_DENIED ); break;
384 case EROFS: SET_ERROR( ERROR_WRITE_PROTECT ); break;
385 case EBUSY: SET_ERROR( ERROR_LOCK_VIOLATION ); break;
386 case ENOENT: SET_ERROR( ERROR_FILE_NOT_FOUND ); break;
387 case EISDIR: SET_ERROR( ERROR_CANNOT_MAKE ); break;
388 case ENFILE:
389 case EMFILE: SET_ERROR( ERROR_NO_MORE_FILES ); break;
390 case EEXIST: SET_ERROR( ERROR_FILE_EXISTS ); break;
391 case EINVAL: SET_ERROR( ERROR_INVALID_PARAMETER ); break;
392 case ESPIPE: SET_ERROR( ERROR_SEEK ); break;
393 case ENOTEMPTY: SET_ERROR( ERROR_DIR_NOT_EMPTY ); break;
394 default: perror("file_set_error"); SET_ERROR( ERROR_UNKNOWN ); break;
398 struct file *get_file_obj( struct process *process, int handle,
399 unsigned int access )
401 return (struct file *)get_handle_obj( current->process, handle,
402 access, &file_ops );
405 int file_get_mmap_fd( struct file *file )
407 return dup( file->select.fd );
410 static int set_file_pointer( int handle, int *low, int *high, int whence )
412 struct file *file;
413 int result;
415 if (*high)
417 fprintf( stderr, "set_file_pointer: offset > 4Gb not supported yet\n" );
418 SET_ERROR( ERROR_INVALID_PARAMETER );
419 return 0;
422 if (!(file = get_file_obj( current->process, handle, 0 )))
423 return 0;
424 if ((result = lseek( file->select.fd, *low, whence )) == -1)
426 /* Check for seek before start of file */
427 if ((errno == EINVAL) && (whence != SEEK_SET) && (*low < 0))
428 SET_ERROR( ERROR_NEGATIVE_SEEK );
429 else
430 file_set_error();
431 release_object( file );
432 return 0;
434 *low = result;
435 release_object( file );
436 return 1;
439 static int truncate_file( int handle )
441 struct file *file;
442 int result;
444 if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
445 return 0;
446 if (((result = lseek( file->select.fd, 0, SEEK_CUR )) == -1) ||
447 (ftruncate( file->select.fd, result ) == -1))
449 file_set_error();
450 release_object( file );
451 return 0;
453 release_object( file );
454 return 1;
458 /* try to grow the file to the specified size */
459 int grow_file( struct file *file, int size_high, int size_low )
461 struct stat st;
463 if (size_high)
465 SET_ERROR( ERROR_INVALID_PARAMETER );
466 return 0;
468 if (fstat( file->select.fd, &st ) == -1)
470 file_set_error();
471 return 0;
473 if (st.st_size >= size_low) return 1; /* already large enough */
474 if (ftruncate( file->select.fd, size_low ) != -1) return 1;
475 file_set_error();
476 return 0;
479 static int set_file_time( int handle, time_t access_time, time_t write_time )
481 struct file *file;
482 struct utimbuf utimbuf;
484 if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
485 return 0;
486 if (!access_time || !write_time)
488 struct stat st;
489 if (stat( file->name, &st ) == -1) goto error;
490 if (!access_time) access_time = st.st_atime;
491 if (!write_time) write_time = st.st_mtime;
493 utimbuf.actime = access_time;
494 utimbuf.modtime = write_time;
495 if (utime( file->name, &utimbuf ) == -1) goto error;
496 release_object( file );
497 return 1;
498 error:
499 file_set_error();
500 release_object( file );
501 return 0;
504 static int file_lock( struct file *file, int offset_high, int offset_low,
505 int count_high, int count_low )
507 /* FIXME: implement this */
508 return 1;
511 static int file_unlock( struct file *file, int offset_high, int offset_low,
512 int count_high, int count_low )
514 /* FIXME: implement this */
515 return 1;
517 /* create a file */
518 DECL_HANDLER(create_file)
520 struct create_file_reply reply = { -1 };
521 struct object *obj;
522 char *name = (char *)data;
523 if (!len) name = NULL;
524 else CHECK_STRING( "create_file", name, len );
526 if ((obj = create_file( fd, name, req->access,
527 req->sharing, req->create, req->attrs )) != NULL)
529 reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
530 release_object( obj );
532 send_reply( current, -1, 1, &reply, sizeof(reply) );
535 /* get a Unix fd to read from a file */
536 DECL_HANDLER(get_read_fd)
538 struct object *obj;
539 int read_fd;
541 if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
543 read_fd = obj->ops->get_read_fd( obj );
544 release_object( obj );
546 else read_fd = -1;
547 send_reply( current, read_fd, 0 );
550 /* get a Unix fd to write to a file */
551 DECL_HANDLER(get_write_fd)
553 struct object *obj;
554 int write_fd;
556 if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
558 write_fd = obj->ops->get_write_fd( obj );
559 release_object( obj );
561 else write_fd = -1;
562 send_reply( current, write_fd, 0 );
565 /* set a file current position */
566 DECL_HANDLER(set_file_pointer)
568 struct set_file_pointer_reply reply;
569 reply.low = req->low;
570 reply.high = req->high;
571 set_file_pointer( req->handle, &reply.low, &reply.high, req->whence );
572 send_reply( current, -1, 1, &reply, sizeof(reply) );
575 /* truncate (or extend) a file */
576 DECL_HANDLER(truncate_file)
578 truncate_file( req->handle );
579 send_reply( current, -1, 0 );
582 /* flush a file buffers */
583 DECL_HANDLER(flush_file)
585 struct object *obj;
587 if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
589 obj->ops->flush( obj );
590 release_object( obj );
592 send_reply( current, -1, 0 );
595 /* set a file access and modification times */
596 DECL_HANDLER(set_file_time)
598 set_file_time( req->handle, req->access_time, req->write_time );
599 send_reply( current, -1, 0 );
602 /* get a file information */
603 DECL_HANDLER(get_file_info)
605 struct object *obj;
606 struct get_file_info_reply reply;
608 if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
610 obj->ops->get_file_info( obj, &reply );
611 release_object( obj );
613 send_reply( current, -1, 1, &reply, sizeof(reply) );
616 /* lock a region of a file */
617 DECL_HANDLER(lock_file)
619 struct file *file;
621 if ((file = get_file_obj( current->process, req->handle, 0 )))
623 file_lock( file, req->offset_high, req->offset_low,
624 req->count_high, req->count_low );
625 release_object( file );
627 send_reply( current, -1, 0 );
630 /* unlock a region of a file */
631 DECL_HANDLER(unlock_file)
633 struct file *file;
635 if ((file = get_file_obj( current->process, req->handle, 0 )))
637 file_unlock( file, req->offset_high, req->offset_low,
638 req->count_high, req->count_low );
639 release_object( file );
641 send_reply( current, -1, 0 );