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