Coverage Report

Created: 2023-03-26 06:28

/src/httpd/srclib/apr/file_io/unix/seek.c
Line
Count
Source (jump to first uncovered line)
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
19
static apr_status_t setptr(apr_file_t *thefile, apr_off_t pos )
20
0
{
21
0
    apr_off_t newbufpos;
22
0
    apr_status_t rv;
23
24
0
    if (thefile->direction == 1) {
25
0
        rv = apr_file_flush_locked(thefile);
26
0
        if (rv) {
27
0
            return rv;
28
0
        }
29
0
        thefile->bufpos = thefile->direction = thefile->dataRead = 0;
30
0
    }
31
32
0
    newbufpos = pos - (thefile->filePtr - thefile->dataRead);
33
0
    if (newbufpos >= 0 && newbufpos <= thefile->dataRead) {
34
0
        thefile->bufpos = newbufpos;
35
0
        rv = APR_SUCCESS;
36
0
    }
37
0
    else {
38
0
        if (lseek(thefile->filedes, pos, SEEK_SET) != -1) {
39
0
            thefile->bufpos = thefile->dataRead = 0;
40
0
            thefile->filePtr = pos;
41
0
            rv = APR_SUCCESS;
42
0
        }
43
0
        else {
44
0
            rv = errno;
45
0
        }
46
0
    }
47
48
0
    return rv;
49
0
}
50
51
52
APR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t where, apr_off_t *offset)
53
0
{
54
0
    apr_off_t rv;
55
56
0
    thefile->eof_hit = 0;
57
58
0
    if (thefile->buffered) {
59
0
        int rc = EINVAL;
60
0
        apr_finfo_t finfo;
61
62
0
        file_lock(thefile);
63
64
0
        switch (where) {
65
0
        case APR_SET:
66
0
            rc = setptr(thefile, *offset);
67
0
            break;
68
69
0
        case APR_CUR:
70
0
            rc = setptr(thefile, thefile->filePtr - thefile->dataRead + thefile->bufpos + *offset);
71
0
            break;
72
73
0
        case APR_END:
74
0
            rc = apr_file_info_get_locked(&finfo, APR_FINFO_SIZE, thefile);
75
0
            if (rc == APR_SUCCESS)
76
0
                rc = setptr(thefile, finfo.size + *offset);
77
0
            break;
78
0
        }
79
80
0
        *offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
81
82
0
        file_unlock(thefile);
83
84
0
        return rc;
85
0
    }
86
0
    else {
87
0
        rv = lseek(thefile->filedes, *offset, where);
88
0
        if (rv == -1) {
89
0
            *offset = -1;
90
0
            return errno;
91
0
        }
92
0
        else {
93
0
            *offset = rv;
94
0
            return APR_SUCCESS;
95
0
        }
96
0
    }
97
0
}
98
99
apr_status_t apr_file_trunc(apr_file_t *fp, apr_off_t offset)
100
0
{
101
0
    if (fp->buffered) {
102
0
        int rc = 0;
103
0
        file_lock(fp);
104
0
        if (fp->direction == 1 && fp->bufpos != 0) {
105
0
            apr_off_t len = fp->filePtr + fp->bufpos;
106
0
            if (offset < len) {
107
                /* New file end fall below our write buffer limit.
108
                 * Figure out if and what needs to be flushed.
109
                 */
110
0
                apr_off_t off = len - offset;
111
0
                if (off >= 0 && off <= fp->bufpos)
112
0
                    fp->bufpos = fp->bufpos - (size_t)off;
113
0
                else
114
0
                    fp->bufpos = 0;
115
0
            }
116
0
            rc = apr_file_flush_locked(fp);
117
            /* Reset buffer positions for write mode */
118
0
            fp->bufpos = fp->direction = fp->dataRead = 0;
119
0
        }
120
0
        else if (fp->direction == 0) {
121
            /* Discard the read buffer, as we are about to reposition
122
             * ourselves to the end of file.
123
             */
124
0
            fp->bufpos = 0;
125
0
            fp->dataRead = 0;
126
0
        }
127
0
        file_unlock(fp);
128
0
        if (rc) {
129
0
            return rc;
130
0
        }
131
0
    }
132
0
    if (ftruncate(fp->filedes, offset) == -1) {
133
0
        return errno;
134
0
    }
135
0
    return apr_file_seek(fp, APR_SET, &offset);
136
0
}