2 * Server-side file management
4 * Copyright (C) 1998 Alexandre Julliard
13 #include <sys/errno.h>
16 #include <sys/types.h>
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 =
67 static int get_name_hash( const char *name )
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 )
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;
96 static struct object *create_file( int fd, const char *name, unsigned int access,
97 unsigned int sharing, int create, unsigned int attrs )
109 SET_ERROR( ERROR_INVALID_PARAMETER );
113 /* check sharing mode */
114 hash = get_name_hash( name );
115 if (!check_sharing( name, hash, access, sharing ))
117 SET_ERROR( ERROR_SHARING_VIOLATION );
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))
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)
145 /* Refuse to open a directory */
146 if (fstat( fd, &st ) == -1)
152 if (S_ISDIR(st.st_mode))
154 SET_ERROR( ERROR_ACCESS_DENIED );
161 if ((fd = dup(fd)) == -1)
168 if (!(file = mem_alloc( sizeof(*file) )))
175 if (!(file->name = mem_alloc( strlen(name) + 1 )))
181 strcpy( file->name, name );
182 file->next = file_hash[hash];
183 file_hash[hash] = file;
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;
196 file->sharing = sharing;
197 register_select_user( &file->select );
202 /* Create a temp file for anonymous mappings */
203 struct file *create_temp_file( int access )
211 if (!(name = tmpnam(NULL)))
213 SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );
216 fd = open( name, O_CREAT | O_EXCL | O_RDWR, 0600 );
217 } while ((fd == -1) && (errno == EEXIST));
225 if (!(file = mem_alloc( sizeof(*file) )))
230 init_object( &file->obj, &file_ops, NULL );
233 file->select.fd = fd;
234 file->select.func = default_select_event;
235 file->select.private = file;
236 file->access = access;
239 register_select_user( &file->select );
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 */
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 );
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 )
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 );
294 /* restart waiting on select() if we are no longer signaled */
295 if (obj->head) set_select_events( &file->select, events );
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 )
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 );
326 static int file_get_info( struct object *obj, struct get_file_info_reply *reply )
329 struct file *file = (struct file *)obj;
330 assert( obj->ops == &file_ops );
332 if (fstat( file->select.fd, &st ) == -1)
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 */
354 static void file_destroy( struct object *obj )
356 struct file *file = (struct file *)obj;
357 assert( obj->ops == &file_ops );
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;
365 *pptr = (*pptr)->next;
366 if (file->flags & FILE_FLAG_DELETE_ON_CLOSE) unlink( file->name );
369 unregister_select_user( &file->select );
370 close( file->select.fd );
374 /* set the last error depending on errno */
375 void file_set_error(void)
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;
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;
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,
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 )
417 fprintf( stderr, "set_file_pointer: offset > 4Gb not supported yet\n" );
418 SET_ERROR( ERROR_INVALID_PARAMETER );
422 if (!(file = get_file_obj( current->process, handle, 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 );
431 release_object( file );
435 release_object( file );
439 static int truncate_file( int handle )
444 if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
446 if (((result = lseek( file->select.fd, 0, SEEK_CUR )) == -1) ||
447 (ftruncate( file->select.fd, result ) == -1))
450 release_object( file );
453 release_object( file );
458 /* try to grow the file to the specified size */
459 int grow_file( struct file *file, int size_high, int size_low )
465 SET_ERROR( ERROR_INVALID_PARAMETER );
468 if (fstat( file->select.fd, &st ) == -1)
473 if (st.st_size >= size_low) return 1; /* already large enough */
474 if (ftruncate( file->select.fd, size_low ) != -1) return 1;
479 static int set_file_time( int handle, time_t access_time, time_t write_time )
482 struct utimbuf utimbuf;
484 if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
486 if (!access_time || !write_time)
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 );
500 release_object( file );
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 */
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 */
518 DECL_HANDLER(create_file)
520 struct create_file_reply reply = { -1 };
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)
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 );
547 send_reply( current, read_fd, 0 );
550 /* get a Unix fd to write to a file */
551 DECL_HANDLER(get_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 );
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)
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)
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)
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)
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 );