123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define INCL_DOS
- #define INCL_DOSERRORS
- #include "fspr_arch_file_io.h"
- #include "fspr_file_io.h"
- #include "fspr_lib.h"
- #include "fspr_strings.h"
- #include <malloc.h>
- APR_DECLARE(fspr_status_t) fspr_file_read(fspr_file_t *thefile, void *buf, fspr_size_t *nbytes)
- {
- ULONG rc = 0;
- ULONG bytesread;
- if (!thefile->isopen) {
- *nbytes = 0;
- return APR_EBADF;
- }
- if (thefile->buffered) {
- char *pos = (char *)buf;
- ULONG blocksize;
- ULONG size = *nbytes;
- fspr_thread_mutex_lock(thefile->mutex);
- if (thefile->direction == 1) {
- int rv = fspr_file_flush(thefile);
- if (rv != APR_SUCCESS) {
- fspr_thread_mutex_unlock(thefile->mutex);
- return rv;
- }
- thefile->bufpos = 0;
- thefile->direction = 0;
- thefile->dataRead = 0;
- }
- while (rc == 0 && size > 0) {
- if (thefile->bufpos >= thefile->dataRead) {
- ULONG bytesread;
- rc = DosRead(thefile->filedes, thefile->buffer,
- APR_FILE_BUFSIZE, &bytesread);
- if (bytesread == 0) {
- if (rc == 0)
- thefile->eof_hit = TRUE;
- break;
- }
- thefile->dataRead = bytesread;
- thefile->filePtr += thefile->dataRead;
- thefile->bufpos = 0;
- }
- blocksize = size > thefile->dataRead - thefile->bufpos ? thefile->dataRead - thefile->bufpos : size;
- memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
- thefile->bufpos += blocksize;
- pos += blocksize;
- size -= blocksize;
- }
- *nbytes = rc == 0 ? pos - (char *)buf : 0;
- fspr_thread_mutex_unlock(thefile->mutex);
- if (*nbytes == 0 && rc == 0 && thefile->eof_hit) {
- return APR_EOF;
- }
- return APR_FROM_OS_ERROR(rc);
- } else {
- if (thefile->pipe)
- DosResetEventSem(thefile->pipeSem, &rc);
- rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
- if (rc == ERROR_NO_DATA && thefile->timeout != 0) {
- int rcwait = DosWaitEventSem(thefile->pipeSem, thefile->timeout >= 0 ? thefile->timeout / 1000 : SEM_INDEFINITE_WAIT);
- if (rcwait == 0) {
- rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
- }
- else if (rcwait == ERROR_TIMEOUT) {
- *nbytes = 0;
- return APR_TIMEUP;
- }
- }
- if (rc) {
- *nbytes = 0;
- return APR_FROM_OS_ERROR(rc);
- }
- *nbytes = bytesread;
-
- if (bytesread == 0) {
- thefile->eof_hit = TRUE;
- return APR_EOF;
- }
- return APR_SUCCESS;
- }
- }
- APR_DECLARE(fspr_status_t) fspr_file_write(fspr_file_t *thefile, const void *buf, fspr_size_t *nbytes)
- {
- ULONG rc = 0;
- ULONG byteswritten;
- if (!thefile->isopen) {
- *nbytes = 0;
- return APR_EBADF;
- }
- if (thefile->buffered) {
- char *pos = (char *)buf;
- int blocksize;
- int size = *nbytes;
- fspr_thread_mutex_lock(thefile->mutex);
- if ( thefile->direction == 0 ) {
- // Position file pointer for writing at the offset we are logically reading from
- ULONG offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
- if (offset != thefile->filePtr)
- DosSetFilePtr(thefile->filedes, offset, FILE_BEGIN, &thefile->filePtr );
- thefile->bufpos = thefile->dataRead = 0;
- thefile->direction = 1;
- }
- while (rc == 0 && size > 0) {
- if (thefile->bufpos == APR_FILE_BUFSIZE) // write buffer is full
- rc = fspr_file_flush(thefile);
- blocksize = size > APR_FILE_BUFSIZE - thefile->bufpos ? APR_FILE_BUFSIZE - thefile->bufpos : size;
- memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
- thefile->bufpos += blocksize;
- pos += blocksize;
- size -= blocksize;
- }
- fspr_thread_mutex_unlock(thefile->mutex);
- return APR_FROM_OS_ERROR(rc);
- } else {
- if (thefile->flags & APR_APPEND) {
- FILELOCK all = { 0, 0x7fffffff };
- ULONG newpos;
- rc = DosSetFileLocks(thefile->filedes, NULL, &all, -1, 0);
- if (rc == 0) {
- rc = DosSetFilePtr(thefile->filedes, 0, FILE_END, &newpos);
- if (rc == 0) {
- rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
- }
- DosSetFileLocks(thefile->filedes, &all, NULL, -1, 0);
- }
- } else {
- rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
- }
- if (rc) {
- *nbytes = 0;
- return APR_FROM_OS_ERROR(rc);
- }
- *nbytes = byteswritten;
- return APR_SUCCESS;
- }
- }
- #ifdef HAVE_WRITEV
- APR_DECLARE(fspr_status_t) fspr_file_writev(fspr_file_t *thefile, const struct iovec *vec, fspr_size_t nvec, fspr_size_t *nbytes)
- {
- int bytes;
- if ((bytes = writev(thefile->filedes, vec, nvec)) < 0) {
- *nbytes = 0;
- return errno;
- }
- else {
- *nbytes = bytes;
- return APR_SUCCESS;
- }
- }
- #endif
- APR_DECLARE(fspr_status_t) fspr_file_putc(char ch, fspr_file_t *thefile)
- {
- ULONG rc;
- ULONG byteswritten;
- if (!thefile->isopen) {
- return APR_EBADF;
- }
- rc = DosWrite(thefile->filedes, &ch, 1, &byteswritten);
- if (rc) {
- return APR_FROM_OS_ERROR(rc);
- }
-
- return APR_SUCCESS;
- }
- APR_DECLARE(fspr_status_t) fspr_file_ungetc(char ch, fspr_file_t *thefile)
- {
- fspr_off_t offset = -1;
- return fspr_file_seek(thefile, APR_CUR, &offset);
- }
- APR_DECLARE(fspr_status_t) fspr_file_getc(char *ch, fspr_file_t *thefile)
- {
- ULONG rc;
- fspr_size_t bytesread;
- if (!thefile->isopen) {
- return APR_EBADF;
- }
- bytesread = 1;
- rc = fspr_file_read(thefile, ch, &bytesread);
- if (rc) {
- return rc;
- }
-
- if (bytesread == 0) {
- thefile->eof_hit = TRUE;
- return APR_EOF;
- }
-
- return APR_SUCCESS;
- }
- APR_DECLARE(fspr_status_t) fspr_file_puts(const char *str, fspr_file_t *thefile)
- {
- fspr_size_t len;
- len = strlen(str);
- return fspr_file_write(thefile, str, &len);
- }
- APR_DECLARE(fspr_status_t) fspr_file_flush(fspr_file_t *thefile)
- {
- if (thefile->buffered) {
- ULONG written = 0;
- int rc = 0;
- if (thefile->direction == 1 && thefile->bufpos) {
- rc = DosWrite(thefile->filedes, thefile->buffer, thefile->bufpos, &written);
- thefile->filePtr += written;
- if (rc == 0)
- thefile->bufpos = 0;
- }
- return APR_FROM_OS_ERROR(rc);
- } else {
- /* There isn't anything to do if we aren't buffering the output
- * so just return success.
- */
- return APR_SUCCESS;
- }
- }
- APR_DECLARE(fspr_status_t) fspr_file_gets(char *str, int len, fspr_file_t *thefile)
- {
- fspr_size_t readlen;
- fspr_status_t rv = APR_SUCCESS;
- int i;
- for (i = 0; i < len-1; i++) {
- readlen = 1;
- rv = fspr_file_read(thefile, str+i, &readlen);
- if (rv != APR_SUCCESS) {
- break;
- }
- if (readlen != 1) {
- rv = APR_EOF;
- break;
- }
-
- if (str[i] == '\n') {
- i++;
- break;
- }
- }
- str[i] = 0;
- if (i > 0) {
- /* we stored chars; don't report EOF or any other errors;
- * the app will find out about that on the next call
- */
- return APR_SUCCESS;
- }
- return rv;
- }
- APR_DECLARE_NONSTD(int) fspr_file_printf(fspr_file_t *fptr,
- const char *format, ...)
- {
- int cc;
- va_list ap;
- char *buf;
- int len;
- buf = malloc(HUGE_STRING_LEN);
- if (buf == NULL) {
- return 0;
- }
- va_start(ap, format);
- len = fspr_vsnprintf(buf, HUGE_STRING_LEN, format, ap);
- cc = fspr_file_puts(buf, fptr);
- va_end(ap);
- free(buf);
- return (cc == APR_SUCCESS) ? len : -1;
- }
- fspr_status_t fspr_file_check_read(fspr_file_t *fd)
- {
- int rc;
- if (!fd->pipe)
- return APR_SUCCESS; /* Not a pipe, assume no waiting */
- rc = DosWaitEventSem(fd->pipeSem, SEM_IMMEDIATE_RETURN);
- if (rc == ERROR_TIMEOUT)
- return APR_TIMEUP;
- return APR_FROM_OS_ERROR(rc);
- }
|