Rev 4921 | Rev 5215 | 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; |
||
81 | continue; |
||
82 | } |
||
83 | *ptr++ = '/'; |
||
84 | if (*file == '/') |
||
85 | ++file; |
||
86 | while (*file && *file!='/') |
||
87 | *ptr++ = *file++; |
||
88 | } |
||
89 | *ptr = 0; |
||
90 | }; |
||
91 | |||
92 | static char *getccwd(char *buf, size_t size) |
||
93 | { |
||
94 | int bsize; |
||
95 | __asm__ __volatile__( |
||
96 | "int $0x40" |
||
97 | :"=a"(bsize) |
||
98 | :"a"(30),"b"(2),"c"(buf), "d"(size) |
||
99 | :"memory"); |
||
100 | |||
101 | return buf; |
||
102 | }; |
||
103 | |||
4921 | Serge | 104 | int open (const char * filename, int flags, ...) |
105 | { |
||
5198 | serge | 106 | char buf[1024]; |
107 | |||
4921 | Serge | 108 | __io_handle *ioh; |
109 | fileinfo_t info; |
||
110 | int iomode, rwmode, offset; |
||
111 | int hid; |
||
112 | int err; |
||
113 | |||
114 | hid = __io_alloc(); |
||
115 | if(hid < 0) |
||
116 | { |
||
117 | errno = EMFILE; |
||
118 | return (-1); |
||
119 | }; |
||
120 | |||
5198 | serge | 121 | if (filename[0]=='/') |
122 | { |
||
123 | strcpy(buf,filename); |
||
124 | } |
||
125 | else |
||
126 | { |
||
127 | getccwd(buf, 1024); |
||
128 | buildpath(buf, filename); |
||
129 | } |
||
4921 | Serge | 130 | |
5198 | serge | 131 | // printf("%s %s\n", __FUNCTION__, buf); |
4921 | Serge | 132 | |
5198 | serge | 133 | err = get_fileinfo(buf, &info); |
134 | |||
4921 | Serge | 135 | if( flags & O_EXCL && |
136 | flags & O_CREAT ) |
||
137 | { |
||
138 | if( !err ) |
||
139 | { |
||
140 | errno = EEXIST; |
||
141 | return (-1); |
||
142 | }; |
||
143 | } |
||
144 | |||
145 | if( err ) |
||
146 | { |
||
147 | if(flags & O_CREAT) |
||
5198 | serge | 148 | err=create_file(buf); |
4921 | Serge | 149 | if( err ) |
150 | { |
||
151 | errno = EACCES; |
||
152 | return -1; |
||
153 | }; |
||
154 | }; |
||
155 | |||
156 | if( flags & O_TRUNC ) |
||
5198 | serge | 157 | set_file_size(buf, 0); |
4921 | Serge | 158 | |
159 | ioh = &__io_tab[hid]; |
||
160 | |||
161 | rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR ); |
||
162 | |||
163 | iomode = 0; |
||
164 | offset = 0; |
||
165 | |||
166 | if( rwmode == O_RDWR ) |
||
167 | iomode |= _READ | _WRITE; |
||
168 | else if( rwmode == O_RDONLY) |
||
169 | iomode |= _READ; |
||
170 | else if( rwmode == O_WRONLY) |
||
171 | iomode |= _WRITE; |
||
172 | |||
173 | if( flags & O_APPEND ) |
||
174 | { |
||
175 | iomode |= _APPEND; |
||
176 | offset = info.size; |
||
177 | }; |
||
178 | |||
179 | if( flags & (O_BINARY|O_TEXT) ) |
||
180 | { |
||
181 | if( flags & O_BINARY ) |
||
182 | iomode |= _BINARY; |
||
183 | } else |
||
184 | iomode |= _BINARY; |
||
185 | |||
5198 | serge | 186 | ioh->name = strdup(buf); |
4921 | Serge | 187 | ioh->offset = offset; |
188 | ioh->mode = iomode; |
||
189 | ioh->read = read_file; |
||
190 | ioh->write = write_file; |
||
191 | |||
5198 | serge | 192 | // printf("%s %s\n", __FUNCTION__, ioh->name); |
193 | |||
4921 | Serge | 194 | return hid; |
195 | };> |
||
196 |