11539Srgrimes/* Licensed to the Apache Software Foundation (ASF) under one or more 21539Srgrimes * contributor license agreements. See the NOTICE file distributed with 31539Srgrimes * this work for additional information regarding copyright ownership. 41539Srgrimes * The ASF licenses this file to You under the Apache License, Version 2.0 51539Srgrimes * (the "License"); you may not use this file except in compliance with 61539Srgrimes * the License. You may obtain a copy of the License at 71539Srgrimes * 81539Srgrimes * http://www.apache.org/licenses/LICENSE-2.0 91539Srgrimes * 101539Srgrimes * Unless required by applicable law or agreed to in writing, software 111539Srgrimes * distributed under the License is distributed on an "AS IS" BASIS, 121539Srgrimes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131539Srgrimes * See the License for the specific language governing permissions and 141539Srgrimes * limitations under the License. 151539Srgrimes */ 161539Srgrimes 171539Srgrimes#include "apr_arch_file_io.h" 181539Srgrimes 191539Srgrimesstatic apr_status_t setptr(apr_file_t *thefile, apr_off_t pos ) 201539Srgrimes{ 211539Srgrimes apr_off_t newbufpos; 221539Srgrimes apr_status_t rv; 231539Srgrimes 241539Srgrimes if (thefile->direction == 1) { 251539Srgrimes rv = apr_file_flush_locked(thefile); 261539Srgrimes if (rv) { 271539Srgrimes return rv; 281539Srgrimes } 291539Srgrimes thefile->bufpos = thefile->direction = thefile->dataRead = 0; 301539Srgrimes } 311539Srgrimes 321539Srgrimes newbufpos = pos - (thefile->filePtr - thefile->dataRead); 331539Srgrimes if (newbufpos >= 0 && newbufpos <= thefile->dataRead) { 341539Srgrimes thefile->bufpos = newbufpos; 351539Srgrimes rv = APR_SUCCESS; 361539Srgrimes } 3793032Simp else { 381539Srgrimes if (lseek(thefile->filedes, pos, SEEK_SET) != -1) { 391539Srgrimes thefile->bufpos = thefile->dataRead = 0; 401539Srgrimes thefile->filePtr = pos; 411539Srgrimes rv = APR_SUCCESS; 421539Srgrimes } 431539Srgrimes else { 441539Srgrimes rv = errno; 451539Srgrimes } 461539Srgrimes } 471539Srgrimes 481539Srgrimes return rv; 491539Srgrimes} 501539Srgrimes 511539Srgrimes 521539SrgrimesAPR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t where, apr_off_t *offset) 5314352Sjkh{ 541539Srgrimes apr_off_t rv; 551539Srgrimes 561539Srgrimes thefile->eof_hit = 0; 571539Srgrimes 581539Srgrimes if (thefile->buffered) { 591539Srgrimes int rc = EINVAL; 601539Srgrimes apr_finfo_t finfo; 611539Srgrimes 621539Srgrimes file_lock(thefile); 631539Srgrimes 641539Srgrimes switch (where) { 651539Srgrimes case APR_SET: 661539Srgrimes rc = setptr(thefile, *offset); 6793032Simp break; 6893032Simp 6993032Simp case APR_CUR: 7093032Simp rc = setptr(thefile, thefile->filePtr - thefile->dataRead + thefile->bufpos + *offset); 7193032Simp break; 7293032Simp 73189808Sdas case APR_END: 7493032Simp rc = apr_file_info_get_locked(&finfo, APR_FINFO_SIZE, thefile); 75189808Sdas if (rc == APR_SUCCESS) 7693032Simp rc = setptr(thefile, finfo.size + *offset); 7793032Simp break; 7893032Simp } 79189808Sdas 8093032Simp *offset = thefile->filePtr - thefile->dataRead + thefile->bufpos; 81189808Sdas 821539Srgrimes file_unlock(thefile); 831539Srgrimes 841539Srgrimes return rc; 85 } 86 else { 87 rv = lseek(thefile->filedes, *offset, where); 88 if (rv == -1) { 89 *offset = -1; 90 return errno; 91 } 92 else { 93 *offset = rv; 94 return APR_SUCCESS; 95 } 96 } 97} 98 99apr_status_t apr_file_trunc(apr_file_t *fp, apr_off_t offset) 100{ 101 if (fp->buffered) { 102 int rc = 0; 103 file_lock(fp); 104 if (fp->direction == 1 && fp->bufpos != 0) { 105 apr_off_t len = fp->filePtr + fp->bufpos; 106 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 apr_off_t off = len - offset; 111 if (off >= 0 && off <= fp->bufpos) 112 fp->bufpos = fp->bufpos - (size_t)off; 113 else 114 fp->bufpos = 0; 115 } 116 rc = apr_file_flush_locked(fp); 117 /* Reset buffer positions for write mode */ 118 fp->bufpos = fp->direction = fp->dataRead = 0; 119 } 120 file_unlock(fp); 121 if (rc) { 122 return rc; 123 } 124 } 125 if (ftruncate(fp->filedes, offset) == -1) { 126 return errno; 127 } 128 return apr_file_seek(fp, APR_SET, &offset); 129} 130