xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/file_io/os2/open.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "apr_arch_file_io.h"
18 #include "apr_file_io.h"
19 #include "apr_lib.h"
20 #include "apr_portable.h"
21 #include "apr_strings.h"
22 #include "apr_arch_inherit.h"
23 #include <string.h>
24 
apr_file_cleanup(void * thefile)25 apr_status_t apr_file_cleanup(void *thefile)
26 {
27     apr_file_t *file = thefile;
28     return apr_file_close(file);
29 }
30 
31 
32 
apr_file_open(apr_file_t ** new,const char * fname,apr_int32_t flag,apr_fileperms_t perm,apr_pool_t * pool)33 APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname, apr_int32_t flag,  apr_fileperms_t perm, apr_pool_t *pool)
34 {
35     int oflags = 0;
36     int mflags = OPEN_FLAGS_FAIL_ON_ERROR|OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT;
37     int rv;
38     ULONG action;
39     apr_file_t *dafile = (apr_file_t *)apr_palloc(pool, sizeof(apr_file_t));
40 
41     if (flag & APR_FOPEN_NONBLOCK) {
42         return APR_ENOTIMPL;
43     }
44 
45     dafile->pool = pool;
46     dafile->isopen = FALSE;
47     dafile->eof_hit = FALSE;
48     dafile->buffer = NULL;
49     dafile->flags = flag;
50     dafile->blocking = BLK_ON;
51 
52     if ((flag & APR_FOPEN_READ) && (flag & APR_FOPEN_WRITE)) {
53         mflags |= OPEN_ACCESS_READWRITE;
54     } else if (flag & APR_FOPEN_READ) {
55         mflags |= OPEN_ACCESS_READONLY;
56     } else if (flag & APR_FOPEN_WRITE) {
57         mflags |= OPEN_ACCESS_WRITEONLY;
58     } else {
59         dafile->filedes = -1;
60         return APR_EACCES;
61     }
62 
63     dafile->buffered = (flag & APR_FOPEN_BUFFERED) > 0;
64 
65     if (dafile->buffered) {
66         dafile->buffer = apr_palloc(pool, APR_FILE_DEFAULT_BUFSIZE);
67         dafile->bufsize = APR_FILE_DEFAULT_BUFSIZE;
68         rv = apr_thread_mutex_create(&dafile->mutex, 0, pool);
69 
70         if (rv)
71             return rv;
72     }
73 
74     if (flag & APR_FOPEN_CREATE) {
75         oflags |= OPEN_ACTION_CREATE_IF_NEW;
76 
77         if (!(flag & APR_FOPEN_EXCL) && !(flag & APR_FOPEN_TRUNCATE)) {
78             oflags |= OPEN_ACTION_OPEN_IF_EXISTS;
79         }
80     }
81 
82     if ((flag & APR_FOPEN_EXCL) && !(flag & APR_FOPEN_CREATE))
83         return APR_EACCES;
84 
85     if (flag & APR_FOPEN_TRUNCATE) {
86         oflags |= OPEN_ACTION_REPLACE_IF_EXISTS;
87     } else if ((oflags & 0xFF) == 0) {
88         oflags |= OPEN_ACTION_OPEN_IF_EXISTS;
89     }
90 
91     rv = DosOpen(fname, &(dafile->filedes), &action, 0, 0, oflags, mflags, NULL);
92 
93     if (rv == 0 && (flag & APR_FOPEN_APPEND)) {
94         ULONG newptr;
95         rv = DosSetFilePtr(dafile->filedes, 0, FILE_END, &newptr );
96 
97         if (rv)
98             DosClose(dafile->filedes);
99     }
100 
101     if (rv != 0)
102         return APR_FROM_OS_ERROR(rv);
103 
104     dafile->isopen = TRUE;
105     dafile->fname = apr_pstrdup(pool, fname);
106     dafile->filePtr = 0;
107     dafile->bufpos = 0;
108     dafile->dataRead = 0;
109     dafile->direction = 0;
110     dafile->pipe = FALSE;
111 
112     if (!(flag & APR_FOPEN_NOCLEANUP)) {
113         apr_pool_cleanup_register(dafile->pool, dafile, apr_file_cleanup, apr_file_cleanup);
114     }
115 
116     *new = dafile;
117     return APR_SUCCESS;
118 }
119 
120 
121 
apr_file_close(apr_file_t * file)122 APR_DECLARE(apr_status_t) apr_file_close(apr_file_t *file)
123 {
124     ULONG rc;
125     apr_status_t status;
126 
127     if (file && file->isopen) {
128         /* XXX: flush here is not mutex protected */
129         status = apr_file_flush(file);
130         rc = DosClose(file->filedes);
131 
132         if (rc == 0) {
133             file->isopen = FALSE;
134 
135             if (file->flags & APR_FOPEN_DELONCLOSE) {
136                 status = APR_FROM_OS_ERROR(DosDelete(file->fname));
137             }
138             /* else we return the status of the flush attempt
139              * when all else succeeds
140              */
141         } else {
142             return APR_FROM_OS_ERROR(rc);
143         }
144     }
145 
146     if (file->buffered)
147         apr_thread_mutex_destroy(file->mutex);
148 
149     return status;
150 }
151 
152 
153 
apr_file_remove(const char * path,apr_pool_t * pool)154 APR_DECLARE(apr_status_t) apr_file_remove(const char *path, apr_pool_t *pool)
155 {
156     ULONG rc = DosDelete(path);
157     return APR_FROM_OS_ERROR(rc);
158 }
159 
160 
161 
apr_file_rename(const char * from_path,const char * to_path,apr_pool_t * p)162 APR_DECLARE(apr_status_t) apr_file_rename(const char *from_path, const char *to_path,
163                                    apr_pool_t *p)
164 {
165     ULONG rc = DosMove(from_path, to_path);
166 
167     if (rc == ERROR_ACCESS_DENIED || rc == ERROR_ALREADY_EXISTS) {
168         rc = DosDelete(to_path);
169 
170         if (rc == 0 || rc == ERROR_FILE_NOT_FOUND) {
171             rc = DosMove(from_path, to_path);
172         }
173     }
174 
175     return APR_FROM_OS_ERROR(rc);
176 }
177 
178 
179 
apr_os_file_get(apr_os_file_t * thefile,apr_file_t * file)180 APR_DECLARE(apr_status_t) apr_os_file_get(apr_os_file_t *thefile, apr_file_t *file)
181 {
182     *thefile = file->filedes;
183     return APR_SUCCESS;
184 }
185 
186 
187 
apr_os_file_put(apr_file_t ** file,apr_os_file_t * thefile,apr_int32_t flags,apr_pool_t * pool)188 APR_DECLARE(apr_status_t) apr_os_file_put(apr_file_t **file, apr_os_file_t *thefile, apr_int32_t flags, apr_pool_t *pool)
189 {
190     apr_os_file_t *dafile = thefile;
191 
192     (*file) = apr_palloc(pool, sizeof(apr_file_t));
193     (*file)->pool = pool;
194     (*file)->filedes = *dafile;
195     (*file)->isopen = TRUE;
196     (*file)->eof_hit = FALSE;
197     (*file)->flags = flags;
198     (*file)->pipe = FALSE;
199     (*file)->buffered = (flags & APR_FOPEN_BUFFERED) > 0;
200 
201     if ((*file)->buffered) {
202         apr_status_t rv;
203 
204         (*file)->buffer = apr_palloc(pool, APR_FILE_DEFAULT_BUFSIZE);
205         (*file)->bufsize = APR_FILE_DEFAULT_BUFSIZE;
206         rv = apr_thread_mutex_create(&(*file)->mutex, 0, pool);
207 
208         if (rv)
209             return rv;
210     }
211 
212     return APR_SUCCESS;
213 }
214 
215 
apr_file_eof(apr_file_t * fptr)216 APR_DECLARE(apr_status_t) apr_file_eof(apr_file_t *fptr)
217 {
218     if (!fptr->isopen || fptr->eof_hit == 1) {
219         return APR_EOF;
220     }
221     return APR_SUCCESS;
222 }
223 
224 
apr_file_open_flags_stderr(apr_file_t ** thefile,apr_int32_t flags,apr_pool_t * pool)225 APR_DECLARE(apr_status_t) apr_file_open_flags_stderr(apr_file_t **thefile,
226                                                      apr_int32_t flags,
227                                                      apr_pool_t *pool)
228 {
229     apr_os_file_t fd = 2;
230 
231     return apr_os_file_put(thefile, &fd, flags | APR_FOPEN_WRITE, pool);
232 }
233 
234 
apr_file_open_flags_stdout(apr_file_t ** thefile,apr_int32_t flags,apr_pool_t * pool)235 APR_DECLARE(apr_status_t) apr_file_open_flags_stdout(apr_file_t **thefile,
236                                                      apr_int32_t flags,
237                                                      apr_pool_t *pool)
238 {
239     apr_os_file_t fd = 1;
240 
241     return apr_os_file_put(thefile, &fd, flags | APR_FOPEN_WRITE, pool);
242 }
243 
244 
apr_file_open_flags_stdin(apr_file_t ** thefile,apr_int32_t flags,apr_pool_t * pool)245 APR_DECLARE(apr_status_t) apr_file_open_flags_stdin(apr_file_t **thefile,
246                                                     apr_int32_t flags,
247                                                     apr_pool_t *pool)
248 {
249     apr_os_file_t fd = 0;
250 
251     return apr_os_file_put(thefile, &fd, flags | APR_FOPEN_READ, pool);
252 }
253 
254 
apr_file_open_stderr(apr_file_t ** thefile,apr_pool_t * pool)255 APR_DECLARE(apr_status_t) apr_file_open_stderr(apr_file_t **thefile, apr_pool_t *pool)
256 {
257     return apr_file_open_flags_stderr(thefile, 0, pool);
258 }
259 
260 
apr_file_open_stdout(apr_file_t ** thefile,apr_pool_t * pool)261 APR_DECLARE(apr_status_t) apr_file_open_stdout(apr_file_t **thefile, apr_pool_t *pool)
262 {
263     return apr_file_open_flags_stdout(thefile, 0, pool);
264 }
265 
266 
apr_file_open_stdin(apr_file_t ** thefile,apr_pool_t * pool)267 APR_DECLARE(apr_status_t) apr_file_open_stdin(apr_file_t **thefile, apr_pool_t *pool)
268 {
269     return apr_file_open_flags_stdin(thefile, 0, pool);
270 }
271 
272 APR_POOL_IMPLEMENT_ACCESSOR(file);
273 
274 
275 
apr_file_inherit_set(apr_file_t * thefile)276 APR_DECLARE(apr_status_t) apr_file_inherit_set(apr_file_t *thefile)
277 {
278     int rv;
279     ULONG state;
280 
281     rv = DosQueryFHState(thefile->filedes, &state);
282 
283     if (rv == 0 && (state & OPEN_FLAGS_NOINHERIT) != 0) {
284         rv = DosSetFHState(thefile->filedes, state & ~OPEN_FLAGS_NOINHERIT);
285     }
286 
287     return APR_FROM_OS_ERROR(rv);
288 }
289 
290 
291 
apr_file_inherit_unset(apr_file_t * thefile)292 APR_DECLARE(apr_status_t) apr_file_inherit_unset(apr_file_t *thefile)
293 {
294     int rv;
295     ULONG state;
296 
297     rv = DosQueryFHState(thefile->filedes, &state);
298 
299     if (rv == 0 && (state & OPEN_FLAGS_NOINHERIT) == 0) {
300         rv = DosSetFHState(thefile->filedes, state | OPEN_FLAGS_NOINHERIT);
301     }
302 
303     return APR_FROM_OS_ERROR(rv);
304 }
305