Rev 6744 | Go to most recent revision | 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 |
||
18 | #include |
||
19 | #include "glue.h" |
||
20 | #include "io.h" |
||
21 | |||
22 | #undef erro |
||
23 | extern int errno; |
||
24 | |||
5198 | serge | 25 | static inline int is_slash(char c) |
26 | { |
||
27 | return c=='/' || c=='\\'; |
||
28 | } |
||
29 | |||
30 | void fix_slashes(char * in,char * out) |
||
31 | { |
||
32 | int slash_count; |
||
33 | |||
34 | for(slash_count=1;in && out && *in;in++) |
||
35 | { |
||
36 | if(is_slash(*in)) |
||
37 | { |
||
38 | slash_count++; |
||
39 | continue; |
||
40 | } |
||
41 | else |
||
42 | { |
||
43 | if(slash_count) |
||
44 | { |
||
45 | slash_count=0; |
||
46 | *out++='/'; |
||
47 | } |
||
48 | *out++=*in; |
||
49 | } |
||
50 | } |
||
51 | *out='\0'; |
||
52 | }; |
||
53 | |||
54 | |||
55 | void buildpath(char *buf, const char* file) |
||
56 | { |
||
57 | char *ptr; |
||
58 | |||
59 | ptr = buf + strlen(buf); |
||
60 | |||
61 | while (*file) |
||
62 | { |
||
63 | if (file[0] == '.' && file[1] == 0) |
||
64 | break; |
||
65 | |||
66 | if (file[0] == '.' && file[1] == '/') |
||
67 | { |
||
68 | file+=2; |
||
69 | continue; |
||
70 | }; |
||
71 | |||
72 | if (file[0] == '.' && file[1] == '.' && |
||
73 | (file[2] == 0 || file[2] == '/')) |
||
74 | { |
||
75 | while (ptr > buf && ptr[-1] != '/') |
||
76 | --ptr; |
||
77 | file+=2; |
||
78 | if (*file == 0) |
||
79 | break; |
||
80 | ++file; |
||
9346 | Coldy | 81 | //continue; |
82 | goto __do_until_slash; |
||
5198 | serge | 83 | } |
84 | *ptr++ = '/'; |
||
9346 | Coldy | 85 | __do_until_slash: |
5198 | serge | 86 | if (*file == '/') |
87 | ++file; |
||
88 | while (*file && *file!='/') |
||
89 | *ptr++ = *file++; |
||
90 | } |
||
91 | *ptr = 0; |
||
92 | }; |
||
93 | |||
94 | static char *getccwd(char *buf, size_t size) |
||
95 | { |
||
96 | int bsize; |
||
97 | __asm__ __volatile__( |
||
98 | "int $0x40" |
||
99 | :"=a"(bsize) |
||
100 | :"a"(30),"b"(2),"c"(buf), "d"(size) |
||
101 | :"memory"); |
||
102 | |||
103 | return buf; |
||
104 | }; |
||
105 | |||
4921 | Serge | 106 | int open (const char * filename, int flags, ...) |
107 | { |
||
5198 | serge | 108 | char buf[1024]; |
109 | |||
4921 | Serge | 110 | __io_handle *ioh; |
111 | fileinfo_t info; |
||
112 | int iomode, rwmode, offset; |
||
113 | int hid; |
||
114 | int err; |
||
115 | |||
116 | hid = __io_alloc(); |
||
117 | if(hid < 0) |
||
118 | { |
||
119 | errno = EMFILE; |
||
6744 | siemargl | 120 | __io_free(hid); |
4921 | Serge | 121 | return (-1); |
122 | }; |
||
123 | |||
5198 | serge | 124 | if (filename[0]=='/') |
125 | { |
||
126 | strcpy(buf,filename); |
||
127 | } |
||
128 | else |
||
129 | { |
||
130 | getccwd(buf, 1024); |
||
131 | buildpath(buf, filename); |
||
132 | } |
||
4921 | Serge | 133 | |
5198 | serge | 134 | err = get_fileinfo(buf, &info); |
135 | |||
4921 | Serge | 136 | if( flags & O_EXCL && |
137 | flags & O_CREAT ) |
||
138 | { |
||
139 | if( !err ) |
||
140 | { |
||
141 | errno = EEXIST; |
||
6744 | siemargl | 142 | __io_free(hid); |
4921 | Serge | 143 | return (-1); |
144 | }; |
||
145 | } |
||
146 | |||
147 | if( err ) |
||
148 | { |
||
149 | if(flags & O_CREAT) |
||
5198 | serge | 150 | err=create_file(buf); |
4921 | Serge | 151 | if( err ) |
152 | { |
||
153 | errno = EACCES; |
||
6744 | siemargl | 154 | __io_free(hid); |
4921 | Serge | 155 | return -1; |
156 | }; |
||
157 | }; |
||
158 | |||
159 | if( flags & O_TRUNC ) |
||
5198 | serge | 160 | set_file_size(buf, 0); |
4921 | Serge | 161 | |
162 | ioh = &__io_tab[hid]; |
||
163 | |||
164 | rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR ); |
||
165 | |||
166 | iomode = 0; |
||
167 | offset = 0; |
||
168 | |||
169 | if( rwmode == O_RDWR ) |
||
170 | iomode |= _READ | _WRITE; |
||
171 | else if( rwmode == O_RDONLY) |
||
172 | iomode |= _READ; |
||
173 | else if( rwmode == O_WRONLY) |
||
174 | iomode |= _WRITE; |
||
175 | |||
176 | if( flags & O_APPEND ) |
||
177 | { |
||
178 | iomode |= _APPEND; |
||
179 | offset = info.size; |
||
180 | }; |
||
181 | |||
182 | if( flags & (O_BINARY|O_TEXT) ) |
||
183 | { |
||
184 | if( flags & O_BINARY ) |
||
185 | iomode |= _BINARY; |
||
186 | } else |
||
187 | iomode |= _BINARY; |
||
188 | |||
5198 | serge | 189 | ioh->name = strdup(buf); |
4921 | Serge | 190 | ioh->offset = offset; |
191 | ioh->mode = iomode; |
||
192 | ioh->read = read_file; |
||
193 | ioh->write = write_file; |
||
194 | |||
195 | return hid; |
||
196 | };> |
||
197 |