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