diff options
author | Stefan Fritsch <sf@sfritsch.de> | 2011-12-27 19:42:03 +0100 |
---|---|---|
committer | Stefan Fritsch <sf@sfritsch.de> | 2011-12-27 19:42:03 +0100 |
commit | 80db94fff6a9620fb469ee911347ed973e3f7735 (patch) | |
tree | 35ccde4018b7e6b84103e5e85dc1085ef9e7d6c2 /srclib/apr/file_io/os2/readwrite.c | |
download | apache2-80db94fff6a9620fb469ee911347ed973e3f7735.tar.gz |
Upstream tarball 2.2.3upstream/2.2.3
Diffstat (limited to 'srclib/apr/file_io/os2/readwrite.c')
-rw-r--r-- | srclib/apr/file_io/os2/readwrite.c | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/srclib/apr/file_io/os2/readwrite.c b/srclib/apr/file_io/os2/readwrite.c new file mode 100644 index 00000000..fbb0860c --- /dev/null +++ b/srclib/apr/file_io/os2/readwrite.c @@ -0,0 +1,370 @@ +/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed 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 "apr_arch_file_io.h" +#include "apr_file_io.h" +#include "apr_lib.h" +#include "apr_strings.h" + +#include <malloc.h> + +APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_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; + + apr_thread_mutex_lock(thefile->mutex); + + if (thefile->direction == 1) { + int rv = apr_file_flush(thefile); + + if (rv != APR_SUCCESS) { + apr_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; + apr_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(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, apr_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; + + apr_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 = apr_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; + } + + apr_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(apr_status_t) apr_file_writev(apr_file_t *thefile, const struct iovec *vec, apr_size_t nvec, apr_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(apr_status_t) apr_file_putc(char ch, apr_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(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile) +{ + apr_off_t offset = -1; + return apr_file_seek(thefile, APR_CUR, &offset); +} + + +APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile) +{ + ULONG rc; + apr_size_t bytesread; + + if (!thefile->isopen) { + return APR_EBADF; + } + + bytesread = 1; + rc = apr_file_read(thefile, ch, &bytesread); + + if (rc) { + return rc; + } + + if (bytesread == 0) { + thefile->eof_hit = TRUE; + return APR_EOF; + } + + return APR_SUCCESS; +} + + + +APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile) +{ + apr_size_t len; + + len = strlen(str); + return apr_file_write(thefile, str, &len); +} + + +APR_DECLARE(apr_status_t) apr_file_flush(apr_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(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile) +{ + apr_size_t readlen; + apr_status_t rv = APR_SUCCESS; + int i; + + for (i = 0; i < len-1; i++) { + readlen = 1; + rv = apr_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) apr_file_printf(apr_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 = apr_vsnprintf(buf, HUGE_STRING_LEN, format, ap); + cc = apr_file_puts(buf, fptr); + va_end(ap); + free(buf); + return (cc == APR_SUCCESS) ? len : -1; +} + + + +apr_status_t apr_file_check_read(apr_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); +} |