Rev 9346 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4921 | Serge | 1 | /* open.c -- open a file. |
2 | * |
||
3 | * Copyright (c) 1995 Cygnus Support |
||
4 | * |
||
5 | * The authors hereby grant permission to use, copy, modify, distribute, |
||
6 | * and license this software and its documentation for any purpose, provided |
||
7 | * that existing copyright notices are retained in all copies and that this |
||
8 | * notice is included verbatim in any distributions. No written agreement, |
||
9 | * license, or royalty fee is required for any of the authorized uses. |
||
10 | * Modifications to this software may be copyrighted by their authors |
||
11 | * and need not follow the licensing terms described here, provided that |
||
12 | * the new terms are clearly indicated on the first page of each file where |
||
13 | * they apply. |
||
14 | */ |
||
15 | #include |
||
16 | #include |
||
17 | #include |
||
9952 | turbocat | 18 | #include |
19 | |||
4921 | Serge | 20 | #include "glue.h" |
21 | #include "io.h" |
||
22 | |||
9952 | turbocat | 23 | #undef errno |
4921 | Serge | 24 | extern int errno; |
25 | |||
9952 | turbocat | 26 | extern int write_file(const char *path,const void *buff, |
27 | size_t offset, size_t count, size_t *writes); |
||
28 | |||
29 | extern int read_file(const char *path, void *buff, |
||
30 | size_t offset, size_t count, size_t *reads); |
||
31 | |||
5198 | serge | 32 | static inline int is_slash(char c) |
33 | { |
||
34 | return c=='/' || c=='\\'; |
||
35 | } |
||
36 | |||
37 | void fix_slashes(char * in,char * out) |
||
38 | { |
||
39 | int slash_count; |
||
40 | |||
41 | for(slash_count=1;in && out && *in;in++) |
||
42 | { |
||
43 | if(is_slash(*in)) |
||
44 | { |
||
45 | slash_count++; |
||
46 | continue; |
||
47 | } |
||
48 | else |
||
49 | { |
||
50 | if(slash_count) |
||
51 | { |
||
52 | slash_count=0; |
||
53 | *out++='/'; |
||
54 | } |
||
55 | *out++=*in; |
||
56 | } |
||
57 | } |
||
58 | *out='\0'; |
||
9952 | turbocat | 59 | } |
5198 | serge | 60 | |
61 | |||
62 | void buildpath(char *buf, const char* file) |
||
63 | { |
||
64 | char *ptr; |
||
65 | |||
66 | ptr = buf + strlen(buf); |
||
67 | |||
68 | while (*file) |
||
69 | { |
||
70 | if (file[0] == '.' && file[1] == 0) |
||
71 | break; |
||
72 | |||
73 | if (file[0] == '.' && file[1] == '/') |
||
74 | { |
||
75 | file+=2; |
||
76 | continue; |
||
77 | }; |
||
78 | |||
79 | if (file[0] == '.' && file[1] == '.' && |
||
80 | (file[2] == 0 || file[2] == '/')) |
||
81 | { |
||
82 | while (ptr > buf && ptr[-1] != '/') |
||
83 | --ptr; |
||
84 | file+=2; |
||
85 | if (*file == 0) |
||
86 | break; |
||
87 | ++file; |
||
9346 | Coldy | 88 | //continue; |
89 | goto __do_until_slash; |
||
5198 | serge | 90 | } |
91 | *ptr++ = '/'; |
||
9346 | Coldy | 92 | __do_until_slash: |
5198 | serge | 93 | if (*file == '/') |
94 | ++file; |
||
95 | while (*file && *file!='/') |
||
96 | *ptr++ = *file++; |
||
97 | } |
||
98 | *ptr = 0; |
||
9952 | turbocat | 99 | } |
5198 | serge | 100 | |
4921 | Serge | 101 | int open (const char * filename, int flags, ...) |
102 | { |
||
5198 | serge | 103 | char buf[1024]; |
104 | |||
4921 | Serge | 105 | __io_handle *ioh; |
9952 | turbocat | 106 | ksys_file_info_t info; |
4921 | Serge | 107 | int iomode, rwmode, offset; |
108 | int hid; |
||
109 | int err; |
||
110 | |||
111 | hid = __io_alloc(); |
||
112 | if(hid < 0) |
||
113 | { |
||
114 | errno = EMFILE; |
||
6744 | siemargl | 115 | __io_free(hid); |
4921 | Serge | 116 | return (-1); |
117 | }; |
||
118 | |||
5198 | serge | 119 | if (filename[0]=='/') |
120 | { |
||
121 | strcpy(buf,filename); |
||
122 | } |
||
123 | else |
||
124 | { |
||
9952 | turbocat | 125 | _ksys_getcwd(buf, 1024); |
5198 | serge | 126 | buildpath(buf, filename); |
127 | } |
||
4921 | Serge | 128 | |
9952 | turbocat | 129 | err = _ksys_file_info(buf, &info); |
5198 | serge | 130 | |
9952 | turbocat | 131 | if (flags & O_EXCL && |
4921 | Serge | 132 | flags & O_CREAT ) |
133 | { |
||
9952 | turbocat | 134 | if (!err) |
4921 | Serge | 135 | { |
136 | errno = EEXIST; |
||
6744 | siemargl | 137 | __io_free(hid); |
4921 | Serge | 138 | return (-1); |
9952 | turbocat | 139 | } |
4921 | Serge | 140 | } |
141 | |||
9952 | turbocat | 142 | if (err) |
4921 | Serge | 143 | { |
144 | if(flags & O_CREAT) |
||
9952 | turbocat | 145 | err = _ksys_file_create(buf).status; |
146 | if(err) |
||
4921 | Serge | 147 | { |
148 | errno = EACCES; |
||
6744 | siemargl | 149 | __io_free(hid); |
4921 | Serge | 150 | return -1; |
151 | }; |
||
152 | }; |
||
153 | |||
9952 | turbocat | 154 | if (flags & O_TRUNC) |
155 | _ksys_file_set_size(buf, 0); |
||
4921 | Serge | 156 | |
157 | ioh = &__io_tab[hid]; |
||
158 | |||
159 | rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR ); |
||
160 | |||
161 | iomode = 0; |
||
162 | offset = 0; |
||
163 | |||
9952 | turbocat | 164 | if (rwmode == O_RDWR) |
4921 | Serge | 165 | iomode |= _READ | _WRITE; |
9952 | turbocat | 166 | else if (rwmode == O_RDONLY) |
4921 | Serge | 167 | iomode |= _READ; |
9952 | turbocat | 168 | else if (rwmode == O_WRONLY) |
4921 | Serge | 169 | iomode |= _WRITE; |
170 | |||
9952 | turbocat | 171 | if (flags & O_APPEND) |
4921 | Serge | 172 | { |
173 | iomode |= _APPEND; |
||
174 | offset = info.size; |
||
9952 | turbocat | 175 | } |
4921 | Serge | 176 | |
9952 | turbocat | 177 | if (flags & (O_BINARY|O_TEXT)) |
4921 | Serge | 178 | { |
9952 | turbocat | 179 | if (flags & O_BINARY) |
4921 | Serge | 180 | iomode |= _BINARY; |
9952 | turbocat | 181 | } |
182 | else |
||
183 | { |
||
4921 | Serge | 184 | iomode |= _BINARY; |
9952 | turbocat | 185 | } |
4921 | Serge | 186 | |
5198 | serge | 187 | ioh->name = strdup(buf); |
4921 | Serge | 188 | ioh->offset = offset; |
189 | ioh->mode = iomode; |
||
190 | ioh->read = read_file; |
||
191 | ioh->write = write_file; |
||
192 | |||
193 | return hid; |
||
9952 | turbocat | 194 | }> |