ANSI C fixes.
[wine] / server / file.c
1 /*
2  * Server-side file management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
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>
20
21 #include "winerror.h"
22 #include "winbase.h"
23
24 #include "handle.h"
25 #include "thread.h"
26 #include "request.h"
27
28 struct file
29 {
30     struct object       obj;        /* object header */
31     struct select_user  select;     /* select user */
32     struct file        *next;       /* next file in hashing list */
33     char               *name;       /* file name */
34     unsigned int        access;     /* file access (GENERIC_READ/WRITE) */
35     unsigned int        flags;      /* flags (FILE_FLAG_*) */
36     unsigned int        sharing;    /* file sharing mode */
37 };
38
39 #define NAME_HASH_SIZE 37
40
41 static struct file *file_hash[NAME_HASH_SIZE];
42
43 static void file_dump( struct object *obj, int verbose );
44 static int file_add_queue( struct object *obj, struct wait_queue_entry *entry );
45 static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry );
46 static int file_signaled( struct object *obj, struct thread *thread );
47 static int file_get_read_fd( struct object *obj );
48 static int file_get_write_fd( struct object *obj );
49 static int file_flush( struct object *obj );
50 static int file_get_info( struct object *obj, struct get_file_info_request *req );
51 static void file_destroy( struct object *obj );
52
53 static const struct object_ops file_ops =
54 {
55     sizeof(struct file),
56     file_dump,
57     file_add_queue,
58     file_remove_queue,
59     file_signaled,
60     no_satisfied,
61     file_get_read_fd,
62     file_get_write_fd,
63     file_flush,
64     file_get_info,
65     file_destroy
66 };
67
68
69 static int get_name_hash( const char *name )
70 {
71     int hash = 0;
72     while (*name) hash ^= *name++;
73     return hash % NAME_HASH_SIZE;
74 }
75
76 /* check if the desired access is possible without violating */
77 /* the sharing mode of other opens of the same file */
78 static int check_sharing( const char *name, int hash, unsigned int access,
79                           unsigned int sharing )
80 {
81     struct file *file;
82     unsigned int existing_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
83     unsigned int existing_access = 0;
84
85     for (file = file_hash[hash]; file; file = file->next)
86     {
87         if (strcmp( file->name, name )) continue;
88         existing_sharing &= file->sharing;
89         existing_access |= file->access;
90     }
91     if ((access & GENERIC_READ) && !(existing_sharing & FILE_SHARE_READ)) goto error;
92     if ((access & GENERIC_WRITE) && !(existing_sharing & FILE_SHARE_WRITE)) goto error;
93     if ((existing_access & GENERIC_READ) && !(sharing & FILE_SHARE_READ)) goto error;
94     if ((existing_access & GENERIC_WRITE) && !(sharing & FILE_SHARE_WRITE)) goto error;
95     return 1;
96  error:
97     set_error( ERROR_SHARING_VIOLATION );
98     return 0;
99 }
100
101 static struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing,
102                                         unsigned int attrs )
103 {
104     struct file *file;
105     if ((file = alloc_object( &file_ops )))
106     {
107         file->name           = NULL;
108         file->next           = NULL;
109         file->select.fd      = fd;
110         file->select.func    = default_select_event;
111         file->select.private = file;
112         file->access         = access;
113         file->flags          = attrs;
114         file->sharing        = sharing;
115         register_select_user( &file->select );
116     }
117     return file;
118 }
119
120
121 static struct file *create_file( const char *nameptr, size_t len, unsigned int access,
122                                  unsigned int sharing, int create, unsigned int attrs )
123 {
124     struct file *file;
125     int hash, flags;
126     struct stat st;
127     char *name;
128     int fd = -1;
129
130     if (!(name = mem_alloc( len + 1 ))) return NULL;
131     memcpy( name, nameptr, len );
132     name[len] = 0;
133
134     /* check sharing mode */
135     hash = get_name_hash( name );
136     if (!check_sharing( name, hash, access, sharing )) goto error;
137
138     switch(create)
139     {
140     case CREATE_NEW:        flags = O_CREAT | O_EXCL; break;
141     case CREATE_ALWAYS:     flags = O_CREAT | O_TRUNC; break;
142     case OPEN_ALWAYS:       flags = O_CREAT; break;
143     case TRUNCATE_EXISTING: flags = O_TRUNC; break;
144     case OPEN_EXISTING:     flags = 0; break;
145     default:                set_error( ERROR_INVALID_PARAMETER ); goto error;
146     }
147     switch(access & (GENERIC_READ | GENERIC_WRITE))
148     {
149     case 0: break;
150     case GENERIC_READ:  flags |= O_RDONLY; break;
151     case GENERIC_WRITE: flags |= O_WRONLY; break;
152     case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break;
153     }
154
155     /* FIXME: should set error to ERROR_ALREADY_EXISTS if file existed before */
156     if ((fd = open( name, flags | O_NONBLOCK,
157                     (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666 )) == -1)
158         goto file_error;
159     /* refuse to open a directory */
160     if (fstat( fd, &st ) == -1) goto file_error;
161     if (S_ISDIR(st.st_mode))
162     {
163         set_error( ERROR_ACCESS_DENIED );
164         goto error;
165     }            
166
167     if (!(file = create_file_for_fd( fd, access, sharing, attrs ))) goto error;
168     file->name = name;
169     file->next = file_hash[hash];
170     file_hash[hash] = file;
171     return file;
172
173  file_error:
174     file_set_error();
175  error:
176     if (fd != -1) close( fd );
177     free( name );
178     return NULL;
179 }
180
181 /* Create an anonymous Unix file */
182 int create_anonymous_file(void)
183 {
184     char *name;
185     int fd;
186
187     do
188     {
189         if (!(name = tmpnam(NULL)))
190         {
191             set_error( ERROR_TOO_MANY_OPEN_FILES );
192             return -1;
193         }
194         fd = open( name, O_CREAT | O_EXCL | O_RDWR, 0600 );
195     } while ((fd == -1) && (errno == EEXIST));
196     if (fd == -1)
197     {
198         file_set_error();
199         return -1;
200     }
201     unlink( name );
202     return fd;
203 }
204
205 /* Create a temp file for anonymous mappings */
206 struct file *create_temp_file( int access )
207 {
208     struct file *file;
209     int fd;
210
211     if ((fd = create_anonymous_file()) == -1) return NULL;
212     if (!(file = create_file_for_fd( fd, access, 0, 0 ))) close( fd );
213     return file;
214 }
215
216 static void file_dump( struct object *obj, int verbose )
217 {
218     struct file *file = (struct file *)obj;
219     assert( obj->ops == &file_ops );
220     fprintf( stderr, "File fd=%d flags=%08x name='%s'\n",
221              file->select.fd, file->flags, file->name );
222 }
223
224 static int file_add_queue( struct object *obj, struct wait_queue_entry *entry )
225 {
226     struct file *file = (struct file *)obj;
227     assert( obj->ops == &file_ops );
228     if (!obj->head)  /* first on the queue */
229     {
230         int events = 0;
231         if (file->access & GENERIC_READ) events |= READ_EVENT;
232         if (file->access & GENERIC_WRITE) events |= WRITE_EVENT;
233         set_select_events( &file->select, events );
234     }
235     add_queue( obj, entry );
236     return 1;
237 }
238
239 static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry )
240 {
241     struct file *file = (struct file *)grab_object(obj);
242     assert( obj->ops == &file_ops );
243
244     remove_queue( obj, entry );
245     if (!obj->head)  /* last on the queue is gone */
246         set_select_events( &file->select, 0 );
247     release_object( obj );
248 }
249
250 static int file_signaled( struct object *obj, struct thread *thread )
251 {
252     int events = 0;
253     struct file *file = (struct file *)obj;
254     assert( obj->ops == &file_ops );
255
256     if (file->access & GENERIC_READ) events |= READ_EVENT;
257     if (file->access & GENERIC_WRITE) events |= WRITE_EVENT;
258     if (check_select_events( &file->select, events ))
259     {
260         /* stop waiting on select() if we are signaled */
261         set_select_events( &file->select, 0 );
262         return 1;
263     }
264     else
265     {
266         /* restart waiting on select() if we are no longer signaled */
267         if (obj->head) set_select_events( &file->select, events );
268         return 0;
269     }
270 }
271
272 static int file_get_read_fd( struct object *obj )
273 {
274     struct file *file = (struct file *)obj;
275     assert( obj->ops == &file_ops );
276     return dup( file->select.fd );
277 }
278
279 static int file_get_write_fd( struct object *obj )
280 {
281     struct file *file = (struct file *)obj;
282     assert( obj->ops == &file_ops );
283     return dup( file->select.fd );
284 }
285
286 static int file_flush( struct object *obj )
287 {
288     int ret;
289     struct file *file = (struct file *)grab_object(obj);
290     assert( obj->ops == &file_ops );
291
292     ret = (fsync( file->select.fd ) != -1);
293     if (!ret) file_set_error();
294     release_object( file );
295     return ret;
296 }
297
298 static int file_get_info( struct object *obj, struct get_file_info_request *req )
299 {
300     struct stat st;
301     struct file *file = (struct file *)obj;
302     assert( obj->ops == &file_ops );
303
304     if (fstat( file->select.fd, &st ) == -1)
305     {
306         file_set_error();
307         return 0;
308     }
309     if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) ||
310         S_ISSOCK(st.st_mode) || isatty(file->select.fd)) req->type = FILE_TYPE_CHAR;
311     else req->type = FILE_TYPE_DISK;
312     if (S_ISDIR(st.st_mode)) req->attr = FILE_ATTRIBUTE_DIRECTORY;
313     else req->attr = FILE_ATTRIBUTE_ARCHIVE;
314     if (!(st.st_mode & S_IWUSR)) req->attr |= FILE_ATTRIBUTE_READONLY;
315     req->access_time = st.st_atime;
316     req->write_time  = st.st_mtime;
317     req->size_high   = 0;
318     req->size_low    = S_ISDIR(st.st_mode) ? 0 : st.st_size;
319     req->links       = st.st_nlink;
320     req->index_high  = st.st_dev;
321     req->index_low   = st.st_ino;
322     req->serial      = 0; /* FIXME */
323     return 1;
324 }
325
326 static void file_destroy( struct object *obj )
327 {
328     struct file *file = (struct file *)obj;
329     assert( obj->ops == &file_ops );
330
331     if (file->name)
332     {
333         /* remove it from the hashing list */
334         struct file **pptr = &file_hash[get_name_hash( file->name )];
335         while (*pptr && *pptr != file) pptr = &(*pptr)->next;
336         assert( *pptr );
337         *pptr = (*pptr)->next;
338         if (file->flags & FILE_FLAG_DELETE_ON_CLOSE) unlink( file->name );
339         free( file->name );
340     }
341     unregister_select_user( &file->select );
342     close( file->select.fd );
343 }
344
345 /* set the last error depending on errno */
346 void file_set_error(void)
347 {
348     switch (errno)
349     {
350     case EAGAIN:    set_error( ERROR_SHARING_VIOLATION ); break;
351     case EBADF:     set_error( ERROR_INVALID_HANDLE ); break;
352     case ENOSPC:    set_error( ERROR_HANDLE_DISK_FULL ); break;
353     case EACCES:
354     case EPERM:     set_error( ERROR_ACCESS_DENIED ); break;
355     case EROFS:     set_error( ERROR_WRITE_PROTECT ); break;
356     case EBUSY:     set_error( ERROR_LOCK_VIOLATION ); break;
357     case ENOENT:    set_error( ERROR_FILE_NOT_FOUND ); break;
358     case EISDIR:    set_error( ERROR_CANNOT_MAKE ); break;
359     case ENFILE:
360     case EMFILE:    set_error( ERROR_NO_MORE_FILES ); break;
361     case EEXIST:    set_error( ERROR_FILE_EXISTS ); break;
362     case EINVAL:    set_error( ERROR_INVALID_PARAMETER ); break;
363     case ESPIPE:    set_error( ERROR_SEEK ); break;
364     case ENOTEMPTY: set_error( ERROR_DIR_NOT_EMPTY ); break;
365     default:        perror("file_set_error"); set_error( ERROR_UNKNOWN ); break;
366     }
367 }
368
369 struct file *get_file_obj( struct process *process, int handle,
370                            unsigned int access )
371 {
372     return (struct file *)get_handle_obj( current->process, handle,
373                                           access, &file_ops );
374 }
375
376 int file_get_mmap_fd( struct file *file )
377 {
378     return dup( file->select.fd );
379 }
380
381 static int set_file_pointer( int handle, int *low, int *high, int whence )
382 {
383     struct file *file;
384     int result;
385
386     if (*high)
387     {
388         fprintf( stderr, "set_file_pointer: offset > 4Gb not supported yet\n" );
389         set_error( ERROR_INVALID_PARAMETER );
390         return 0;
391     }
392
393     if (!(file = get_file_obj( current->process, handle, 0 )))
394         return 0;
395     if ((result = lseek( file->select.fd, *low, whence )) == -1)
396     {
397         /* Check for seek before start of file */
398         if ((errno == EINVAL) && (whence != SEEK_SET) && (*low < 0))
399             set_error( ERROR_NEGATIVE_SEEK );
400         else
401             file_set_error();
402         release_object( file );
403         return 0;
404     }
405     *low = result;
406     release_object( file );
407     return 1;
408 }
409
410 static int truncate_file( int handle )
411 {
412     struct file *file;
413     int result;
414
415     if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
416         return 0;
417     if (((result = lseek( file->select.fd, 0, SEEK_CUR )) == -1) ||
418         (ftruncate( file->select.fd, result ) == -1))
419     {
420         file_set_error();
421         release_object( file );
422         return 0;
423     }
424     release_object( file );
425     return 1;
426     
427 }
428
429 /* try to grow the file to the specified size */
430 int grow_file( struct file *file, int size_high, int size_low )
431 {
432     struct stat st;
433
434     if (size_high)
435     {
436         set_error( ERROR_INVALID_PARAMETER );
437         return 0;
438     }
439     if (fstat( file->select.fd, &st ) == -1)
440     {
441         file_set_error();
442         return 0;
443     }
444     if (st.st_size >= size_low) return 1;  /* already large enough */
445     if (ftruncate( file->select.fd, size_low ) != -1) return 1;
446     file_set_error();
447     return 0;
448 }
449
450 static int set_file_time( int handle, time_t access_time, time_t write_time )
451 {
452     struct file *file;
453     struct utimbuf utimbuf;
454
455     if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
456         return 0;
457     if (!access_time || !write_time)
458     {
459         struct stat st;
460         if (stat( file->name, &st ) == -1) goto error;
461         if (!access_time) access_time = st.st_atime;
462         if (!write_time) write_time = st.st_mtime;
463     }
464     utimbuf.actime  = access_time;
465     utimbuf.modtime = write_time;
466     if (utime( file->name, &utimbuf ) == -1) goto error;
467     release_object( file );
468     return 1;
469  error:
470     file_set_error();
471     release_object( file );
472     return 0;
473 }
474
475 static int file_lock( struct file *file, int offset_high, int offset_low,
476                       int count_high, int count_low )
477 {
478     /* FIXME: implement this */
479     return 1;
480 }
481
482 static int file_unlock( struct file *file, int offset_high, int offset_low,
483                         int count_high, int count_low )
484 {
485     /* FIXME: implement this */
486     return 1;
487 }
488
489 /* create a file */
490 DECL_HANDLER(create_file)
491 {
492     size_t len = get_req_strlen( req->name );
493     struct file *file;
494
495     req->handle = -1;
496     if ((file = create_file( req->name, len, req->access,
497                              req->sharing, req->create, req->attrs )))
498     {
499         req->handle = alloc_handle( current->process, file, req->access, req->inherit );
500         release_object( file );
501     }
502 }
503
504 /* allocate a file handle for a Unix fd */
505 DECL_HANDLER(alloc_file_handle)
506 {
507     struct file *file;
508
509     req->handle = -1;
510     if ((fd = dup(fd)) != -1)
511     {
512         if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 )))
513         {
514             req->handle = alloc_handle( current->process, file, req->access, 0 );
515             release_object( file );
516         }
517         else close( fd );
518     }
519     else file_set_error();
520 }
521
522 /* get a Unix fd to read from a file */
523 DECL_HANDLER(get_read_fd)
524 {
525     struct object *obj;
526
527     if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
528     {
529         set_reply_fd( current, obj->ops->get_read_fd( obj ) );
530         release_object( obj );
531     }
532 }
533
534 /* get a Unix fd to write to a file */
535 DECL_HANDLER(get_write_fd)
536 {
537     struct object *obj;
538
539     if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
540     {
541         set_reply_fd( current, obj->ops->get_write_fd( obj ) );
542         release_object( obj );
543     }
544 }
545
546 /* set a file current position */
547 DECL_HANDLER(set_file_pointer)
548 {
549     int high = req->high;
550     int low  = req->low;
551     set_file_pointer( req->handle, &low, &high, req->whence );
552     req->new_low  = low;
553     req->new_high = high;
554 }
555
556 /* truncate (or extend) a file */
557 DECL_HANDLER(truncate_file)
558 {
559     truncate_file( req->handle );
560 }
561
562 /* flush a file buffers */
563 DECL_HANDLER(flush_file)
564 {
565     struct object *obj;
566
567     if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
568     {
569         obj->ops->flush( obj );
570         release_object( obj );
571     }
572 }
573
574 /* set a file access and modification times */
575 DECL_HANDLER(set_file_time)
576 {
577     set_file_time( req->handle, req->access_time, req->write_time );
578 }
579
580 /* get a file information */
581 DECL_HANDLER(get_file_info)
582 {
583     struct object *obj;
584
585     if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
586     {
587         obj->ops->get_file_info( obj, req );
588         release_object( obj );
589     }
590 }
591
592 /* lock a region of a file */
593 DECL_HANDLER(lock_file)
594 {
595     struct file *file;
596
597     if ((file = get_file_obj( current->process, req->handle, 0 )))
598     {
599         file_lock( file, req->offset_high, req->offset_low,
600                    req->count_high, req->count_low );
601         release_object( file );
602     }
603 }
604
605 /* unlock a region of a file */
606 DECL_HANDLER(unlock_file)
607 {
608     struct file *file;
609
610     if ((file = get_file_obj( current->process, req->handle, 0 )))
611     {
612         file_unlock( file, req->offset_high, req->offset_low,
613                      req->count_high, req->count_low );
614         release_object( file );
615     }
616 }