1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251875Speter * contributor license agreements. See the NOTICE file distributed with 3251875Speter * this work for additional information regarding copyright ownership. 4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251875Speter * (the "License"); you may not use this file except in compliance with 6251875Speter * the License. You may obtain a copy of the License at 7251875Speter * 8251875Speter * http://www.apache.org/licenses/LICENSE-2.0 9251875Speter * 10251875Speter * Unless required by applicable law or agreed to in writing, software 11251875Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251875Speter * See the License for the specific language governing permissions and 14251875Speter * limitations under the License. 15251875Speter */ 16251875Speter 17251875Speter#include "apr_arch_file_io.h" 18251875Speter 19251875Speterstatic apr_status_t setptr(apr_file_t *thefile, apr_off_t pos ) 20251875Speter{ 21251875Speter apr_off_t newbufpos; 22251875Speter apr_status_t rv; 23251875Speter 24251875Speter if (thefile->direction == 1) { 25251875Speter rv = apr_file_flush_locked(thefile); 26251875Speter if (rv) { 27251875Speter return rv; 28251875Speter } 29251875Speter thefile->bufpos = thefile->direction = thefile->dataRead = 0; 30251875Speter } 31251875Speter 32251875Speter newbufpos = pos - (thefile->filePtr - thefile->dataRead); 33251875Speter if (newbufpos >= 0 && newbufpos <= thefile->dataRead) { 34251875Speter thefile->bufpos = newbufpos; 35251875Speter rv = APR_SUCCESS; 36251875Speter } 37251875Speter else { 38251875Speter if (lseek(thefile->filedes, pos, SEEK_SET) != -1) { 39251875Speter thefile->bufpos = thefile->dataRead = 0; 40251875Speter thefile->filePtr = pos; 41251875Speter rv = APR_SUCCESS; 42251875Speter } 43251875Speter else { 44251875Speter rv = errno; 45251875Speter } 46251875Speter } 47251875Speter 48251875Speter return rv; 49251875Speter} 50251875Speter 51251875Speter 52251875SpeterAPR_DECLARE(apr_status_t) apr_file_seek(apr_file_t *thefile, apr_seek_where_t where, apr_off_t *offset) 53251875Speter{ 54251875Speter apr_off_t rv; 55251875Speter 56251875Speter thefile->eof_hit = 0; 57251875Speter 58251875Speter if (thefile->buffered) { 59251875Speter int rc = EINVAL; 60251875Speter apr_finfo_t finfo; 61251875Speter 62251875Speter file_lock(thefile); 63251875Speter 64251875Speter switch (where) { 65251875Speter case APR_SET: 66251875Speter rc = setptr(thefile, *offset); 67251875Speter break; 68251875Speter 69251875Speter case APR_CUR: 70251875Speter rc = setptr(thefile, thefile->filePtr - thefile->dataRead + thefile->bufpos + *offset); 71251875Speter break; 72251875Speter 73251875Speter case APR_END: 74251875Speter rc = apr_file_info_get_locked(&finfo, APR_FINFO_SIZE, thefile); 75251875Speter if (rc == APR_SUCCESS) 76251875Speter rc = setptr(thefile, finfo.size + *offset); 77251875Speter break; 78251875Speter } 79251875Speter 80251875Speter *offset = thefile->filePtr - thefile->dataRead + thefile->bufpos; 81251875Speter 82251875Speter file_unlock(thefile); 83251875Speter 84251875Speter return rc; 85251875Speter } 86251875Speter else { 87251875Speter rv = lseek(thefile->filedes, *offset, where); 88251875Speter if (rv == -1) { 89251875Speter *offset = -1; 90251875Speter return errno; 91251875Speter } 92251875Speter else { 93251875Speter *offset = rv; 94251875Speter return APR_SUCCESS; 95251875Speter } 96251875Speter } 97251875Speter} 98251875Speter 99251875Speterapr_status_t apr_file_trunc(apr_file_t *fp, apr_off_t offset) 100251875Speter{ 101251875Speter if (fp->buffered) { 102251875Speter int rc = 0; 103251875Speter file_lock(fp); 104251875Speter if (fp->direction == 1 && fp->bufpos != 0) { 105251875Speter apr_off_t len = fp->filePtr + fp->bufpos; 106251875Speter if (offset < len) { 107251875Speter /* New file end fall below our write buffer limit. 108251875Speter * Figure out if and what needs to be flushed. 109251875Speter */ 110251875Speter apr_off_t off = len - offset; 111251875Speter if (off >= 0 && off <= fp->bufpos) 112251875Speter fp->bufpos = fp->bufpos - (size_t)off; 113251875Speter else 114251875Speter fp->bufpos = 0; 115251875Speter } 116251875Speter rc = apr_file_flush_locked(fp); 117251875Speter /* Reset buffer positions for write mode */ 118251875Speter fp->bufpos = fp->direction = fp->dataRead = 0; 119251875Speter } 120253734Speter file_unlock(fp); 121251875Speter if (rc) { 122251875Speter return rc; 123251875Speter } 124251875Speter } 125251875Speter if (ftruncate(fp->filedes, offset) == -1) { 126251875Speter return errno; 127251875Speter } 128251875Speter return apr_file_seek(fp, APR_SET, &offset); 129251875Speter} 130