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 24static 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 56APR_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 107APR_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