xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/file_io/os2/seek.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 <string.h>
21 #include <io.h>
22 
23 
setptr(apr_file_t * thefile,unsigned long pos)24 static apr_status_t setptr(apr_file_t *thefile, unsigned long pos )
25 {
26     long newbufpos;
27     ULONG rc;
28 
29     if (thefile->direction == 1) {
30         /* XXX: flush here is not mutex protected */
31         apr_status_t rv = apr_file_flush(thefile);
32 
33         if (rv != APR_SUCCESS) {
34             return rv;
35         }
36 
37         thefile->bufpos = thefile->direction = thefile->dataRead = 0;
38     }
39 
40     newbufpos = pos - (thefile->filePtr - thefile->dataRead);
41     if (newbufpos >= 0 && newbufpos <= thefile->dataRead) {
42         thefile->bufpos = newbufpos;
43         rc = 0;
44     } else {
45         rc = DosSetFilePtr(thefile->filedes, pos, FILE_BEGIN, &thefile->filePtr );
46 
47         if ( !rc )
48             thefile->bufpos = thefile->dataRead = 0;
49     }
50 
51     return APR_FROM_OS_ERROR(rc);
52 }
53 
54 
55 
apr_file_seek(apr_file_t * thefile,apr_seek_where_t where,apr_off_t * offset)56 APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t where, apr_off_t *offset)
57 {
58     if (!thefile->isopen) {
59         return APR_EBADF;
60     }
61 
62     thefile->eof_hit = 0;
63 
64     if (thefile->buffered) {
65         int rc = EINVAL;
66         apr_finfo_t finfo;
67 
68         switch (where) {
69         case APR_SET:
70             rc = setptr(thefile, *offset);
71             break;
72 
73         case APR_CUR:
74             rc = setptr(thefile, thefile->filePtr - thefile->dataRead + thefile->bufpos + *offset);
75             break;
76 
77         case APR_END:
78             rc = apr_file_info_get(&finfo, APR_FINFO_NORM, thefile);
79             if (rc == APR_SUCCESS)
80                 rc = setptr(thefile, finfo.size + *offset);
81             break;
82         }
83 
84         *offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
85         return rc;
86     } else {
87         switch (where) {
88         case APR_SET:
89             where = FILE_BEGIN;
90             break;
91 
92         case APR_CUR:
93             where = FILE_CURRENT;
94             break;
95 
96         case APR_END:
97             where = FILE_END;
98             break;
99         }
100 
101         return APR_FROM_OS_ERROR(DosSetFilePtr(thefile->filedes, *offset, where, (ULONG *)offset));
102     }
103 }
104 
105 
106 
apr_file_trunc(apr_file_t * fp,apr_off_t offset)107 APR_DECLARE(apr_status_t) apr_file_trunc(apr_file_t *fp, apr_off_t offset)
108 {
109     int rc = DosSetFileSize(fp->filedes, offset);
110 
111     if (rc != 0) {
112         return APR_FROM_OS_ERROR(rc);
113     }
114 
115     if (fp->buffered) {
116         return setptr(fp, offset);
117     }
118 
119     return APR_SUCCESS;
120 }
121