branch update for HEAD-2003021201
[reactos.git] / lib / crtdll / stdio / fopen.c
1 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
2
3 #include <msvcrt/sys/types.h>
4 #include <msvcrt/stdio.h>
5 #include <msvcrt/io.h>
6 #include <msvcrt/fcntl.h>
7 #include <msvcrt/internal/file.h>
8
9 //might change fopen(file,mode) -> fsopen(file,mode,_SH_DENYNO);
10
11 FILE *  __alloc_file(void);
12
13
14 FILE* fopen(const char *file, const char *mode)
15 {
16   FILE *f;
17   int fd, rw, oflags = 0;
18   char tbchar;
19    
20   if (file == 0)
21     return 0;
22   if (mode == 0)
23     return 0;
24
25   f = __alloc_file();
26   if (f == NULL)
27     return NULL;
28
29   rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+'));
30
31   switch (*mode)
32   {
33   case 'a':
34     oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY);
35     break;
36   case 'r':
37     oflags = rw ? O_RDWR : O_RDONLY;
38     break;
39   case 'w':
40     oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY);
41     break;
42   default:
43     return (NULL);
44   }
45   if (mode[1] == '+')
46     tbchar = mode[2];
47   else
48     tbchar = mode[1];
49   if (tbchar == 't')
50     oflags |= O_TEXT;
51   else if (tbchar == 'b')
52     oflags |= O_BINARY;
53   else
54     oflags |= (_fmode & (O_TEXT|O_BINARY));
55
56   fd = _open(file, oflags, 0666);
57   if (fd < 0)
58     return NULL;
59
60 // ms crtdll ensures that writes will end up at the end of file in append mode
61 // we just move the file pointer to the end of file initially
62   if (*mode == 'a')
63     lseek(fd, 0, SEEK_END);
64
65   f->_cnt = 0;
66   f->_file = fd;
67   f->_bufsiz = 0;
68   if (rw)
69     f->_flag = _IOREAD | _IOWRT;
70   else if (*mode == 'r')
71     f->_flag = _IOREAD;
72   else
73     f->_flag = _IOWRT;
74
75   f->_base = f->_ptr = NULL;
76   return f;
77 }