Rev 1693 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1693 | serge | 1 | /* Reentrant versions of open system call. */ |
2 | |||
3 | #include |
||
4 | #include |
||
5 | #include |
||
6 | #include <_syslist.h> |
||
7 | #include |
||
8 | #include |
||
9 | #include |
||
10 | #include |
||
1906 | serge | 11 | #include |
1693 | serge | 12 | |
13 | /* Some targets provides their own versions of this functions. Those |
||
14 | targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */ |
||
15 | |||
16 | #ifdef _REENT_ONLY |
||
17 | #ifndef REENTRANT_SYSCALLS_PROVIDED |
||
18 | #define REENTRANT_SYSCALLS_PROVIDED |
||
19 | #endif |
||
20 | #endif |
||
21 | |||
22 | #ifndef REENTRANT_SYSCALLS_PROVIDED |
||
23 | |||
24 | /* We use the errno variable used by the system dependent layer. */ |
||
25 | |||
26 | /* |
||
27 | FUNCTION |
||
28 | <<_open_r>>---Reentrant version of open |
||
29 | |||
30 | INDEX |
||
31 | _open_r |
||
32 | |||
33 | ANSI_SYNOPSIS |
||
34 | #include |
||
35 | int _open_r(struct _reent *<[ptr]>, |
||
36 | const char *<[file]>, int <[flags]>, int <[mode]>); |
||
37 | |||
38 | TRAD_SYNOPSIS |
||
39 | #include |
||
40 | int _open_r(<[ptr]>, <[file]>, <[flags]>, <[mode]>) |
||
41 | struct _reent *<[ptr]>; |
||
42 | char *<[file]>; |
||
43 | int <[flags]>; |
||
44 | int <[mode]>; |
||
45 | |||
46 | DESCRIPTION |
||
47 | This is a reentrant version of < |
||
48 | takes a pointer to the global data block, which holds |
||
49 | < |
||
50 | */ |
||
51 | |||
52 | |||
53 | |||
54 | #define NULL_HANDLE (int)-1 |
||
55 | #define DUMMY_HANDLE (int)-2 |
||
56 | |||
57 | #define _READ 0x0001 /* file opened for reading */ |
||
58 | #define _WRITE 0x0002 /* file opened for writing */ |
||
59 | #define _UNGET 0x0004 /* ungetc has been done */ |
||
60 | #define _BIGBUF 0x0008 /* big buffer allocated */ |
||
61 | #define _EOF 0x0010 /* EOF has occurred */ |
||
62 | #define _SFERR 0x0020 /* error has occurred on this file */ |
||
63 | #define _APPEND 0x0080 /* file opened for append */ |
||
64 | #define _BINARY 0x0040 /* file is binary, skip CRLF processing */ |
||
65 | #define _TMPFIL 0x0800 /* this is a temporary file */ |
||
66 | #define _DIRTY 0x1000 /* buffer has been modified */ |
||
67 | #define _ISTTY 0x2000 /* is console device */ |
||
68 | #define _DYNAMIC 0x4000 /* FILE is dynamically allocated */ |
||
69 | #define _FILEEXT 0x8000 /* lseek with positive offset has been done */ |
||
70 | #define _COMMIT 0x0001 /* extended flag: commit OS buffers on flush */ |
||
71 | |||
72 | extern int _fmode; |
||
73 | |||
74 | |||
75 | static inline void debug_out(const char val) |
||
76 | { |
||
77 | __asm__ __volatile__( |
||
78 | "int $0x40 \n\t" |
||
79 | ::"a"(63), "b"(1),"c"(val)); |
||
80 | } |
||
81 | |||
82 | int debugwrite(const char *path, const void *buff, |
||
83 | size_t offset, size_t count, size_t *writes) |
||
84 | { |
||
85 | int ret = count; |
||
86 | const char *p = buff; |
||
87 | |||
88 | while (count--) |
||
89 | { |
||
90 | debug_out(*p++); |
||
91 | }; |
||
92 | *writes = ret; |
||
93 | return ret; |
||
94 | }; |
||
95 | |||
96 | static int __openFileHandle(const char *path, int mode, int *err) |
||
97 | { |
||
98 | fileinfo_t info; |
||
99 | __file_handle *handle; |
||
100 | |||
101 | // path = getfullpath(name); |
||
102 | |||
103 | *err = get_fileinfo(path, &info); |
||
104 | |||
105 | if( mode & O_EXCL && mode & O_CREAT ) |
||
106 | { |
||
107 | if( ! *err) |
||
108 | { |
||
109 | *err = EEXIST; |
||
110 | return -1; |
||
111 | }; |
||
112 | } |
||
113 | |||
114 | if( *err) |
||
115 | { |
||
116 | if(mode & O_CREAT) |
||
117 | *err=create_file(path); |
||
118 | |||
119 | if( *err) |
||
120 | { |
||
121 | return -1; |
||
122 | }; |
||
123 | }; |
||
124 | if( mode & O_TRUNC ) |
||
125 | set_file_size(path, 0); |
||
126 | |||
127 | if ( !(handle=(__file_handle*)malloc(sizeof( __file_handle) ))) |
||
128 | { |
||
129 | *err = ENOMEM; |
||
130 | return -1; |
||
131 | }; |
||
132 | |||
133 | handle->name = strdup(path); |
||
134 | handle->offset = 0; |
||
135 | handle->write = write_file; |
||
136 | |||
137 | *err = 0; |
||
138 | |||
139 | return (int)handle; |
||
140 | }; |
||
141 | |||
142 | |||
143 | |||
144 | int |
||
145 | _DEFUN (_open_r, (ptr, file, flags, dmode), |
||
146 | struct _reent *ptr _AND |
||
147 | _CONST char *file _AND |
||
148 | int flags _AND |
||
149 | int dmode) |
||
150 | { |
||
151 | int hid; |
||
152 | int handle; |
||
153 | int err = 0; |
||
154 | unsigned iomode_flags; |
||
155 | int rwmode; |
||
156 | |||
157 | /* |
||
158 | if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC)) |
||
159 | { |
||
160 | ptr->_errno = ENOSYS; |
||
161 | return -1; |
||
162 | } |
||
163 | */ |
||
164 | |||
165 | // First try to get the required slot. |
||
166 | // No point in creating a file only to not use it. JBS 99/10/26 |
||
167 | hid = __allocPOSIXHandle( DUMMY_HANDLE ); |
||
168 | if( hid == -1 ) |
||
169 | { |
||
170 | ptr->_errno = EMFILE; |
||
171 | return( -1 ); |
||
172 | } |
||
173 | |||
174 | handle = __openFileHandle( file, flags, &err); |
||
175 | |||
176 | if( handle == -1 ) |
||
177 | { |
||
178 | __freePOSIXHandle( hid ); |
||
179 | ptr->_errno = err; |
||
180 | return( -1 ); |
||
181 | } |
||
182 | |||
183 | __setOSHandle( hid, handle ); // JBS 99/11/01 |
||
184 | |||
185 | rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT ); |
||
186 | |||
187 | iomode_flags = 0; |
||
188 | |||
189 | if( rwmode == O_RDWR ) iomode_flags |= _READ | _WRITE; |
||
190 | else if( rwmode == O_RDONLY) iomode_flags |= _READ; |
||
191 | else if( rwmode == O_WRONLY) iomode_flags |= _WRITE; |
||
192 | if( flags & O_APPEND ) iomode_flags |= _APPEND; |
||
193 | if( flags & (O_BINARY|O_TEXT) ) { |
||
194 | if( flags & O_BINARY ) iomode_flags |= _BINARY; |
||
195 | } else { |
||
196 | if( _fmode == O_BINARY ) iomode_flags |= _BINARY; |
||
197 | } |
||
198 | __SetIOMode( hid, iomode_flags ); |
||
199 | |||
200 | ptr->_errno = 0; |
||
201 | |||
202 | return (hid); |
||
203 | } |
||
204 | |||
205 | int |
||
206 | _DEFUN (open, (file, flags, ...), |
||
207 | const char *file _AND |
||
208 | int flags _DOTS) |
||
209 | { |
||
210 | va_list ap; |
||
211 | int ret; |
||
212 | |||
213 | va_start (ap, flags); |
||
214 | ret = _open_r (_REENT, file, flags, va_arg (ap, int)); |
||
215 | va_end (ap); |
||
216 | return ret; |
||
217 | } |
||
218 | |||
219 | |||
220 | |||
221 | #endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */ |