summaryrefslogtreecommitdiff
path: root/file_io
diff options
context:
space:
mode:
Diffstat (limited to 'file_io')
-rw-r--r--file_io/netware/mktemp.c2
-rw-r--r--file_io/os2/filesys.c13
-rw-r--r--file_io/unix/readwrite.c66
-rw-r--r--file_io/win32/dir.c4
-rw-r--r--file_io/win32/filedup.c14
-rw-r--r--file_io/win32/open.c6
-rw-r--r--file_io/win32/readwrite.c51
7 files changed, 120 insertions, 36 deletions
diff --git a/file_io/netware/mktemp.c b/file_io/netware/mktemp.c
index 884a8c40b..58e89386b 100644
--- a/file_io/netware/mktemp.c
+++ b/file_io/netware/mktemp.c
@@ -27,7 +27,7 @@ APR_DECLARE(apr_status_t) apr_file_mktemp(apr_file_t **fp, char *template, apr_i
apr_status_t rv;
flags = (!flags) ? APR_CREATE | APR_READ | APR_WRITE |
- APR_DELONCLOSE : flags;
+ APR_DELONCLOSE : flags & ~APR_EXCL;
fd = mkstemp(template);
if (fd == -1) {
diff --git a/file_io/os2/filesys.c b/file_io/os2/filesys.c
index b323e488d..ef597b38e 100644
--- a/file_io/os2/filesys.c
+++ b/file_io/os2/filesys.c
@@ -94,12 +94,13 @@ apr_status_t filepath_drive_get(char **rootpath, char drive,
apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p)
{
- char path[APR_PATH_MAX];
-
- strcpy(path, root);
- if (path[1] == ':')
- path[0] = apr_toupper(path[0]);
- *rootpath = apr_pstrdup(p, path);
+ if (root[0] && apr_islower(root[0]) && root[1] == ':') {
+ *rootpath = apr_pstrdup(p, root);
+ (*rootpath)[0] = apr_toupper((*rootpath)[0]);
+ }
+ else {
+ *rootpath = root;
+ }
return APR_SUCCESS;
}
diff --git a/file_io/unix/readwrite.c b/file_io/unix/readwrite.c
index 1e6a6e665..98a11421d 100644
--- a/file_io/unix/readwrite.c
+++ b/file_io/unix/readwrite.c
@@ -24,9 +24,6 @@
#define USE_WAIT_FOR_IO
#endif
-/* problems:
- * 1) ungetchar not used for buffered files
- */
APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *nbytes)
{
apr_ssize_t rv;
@@ -311,18 +308,65 @@ APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile)
return APR_SUCCESS;
}
- while (str < final) { /* leave room for trailing '\0' */
- nbytes = 1;
- rv = apr_file_read(thefile, str, &nbytes);
- if (rv != APR_SUCCESS) {
- break;
+ /* If we have an underlying buffer, we can be *much* more efficient
+ * and skip over the apr_file_read calls.
+ */
+ if (thefile->buffered) {
+
+#if APR_HAS_THREADS
+ if (thefile->thlock) {
+ apr_thread_mutex_lock(thefile->thlock);
+ }
+#endif
+
+ if (thefile->direction == 1) {
+ apr_file_flush(thefile);
+ thefile->direction = 0;
+ thefile->bufpos = 0;
+ thefile->dataRead = 0;
}
- if (*str == '\n') {
+
+ while (str < final) { /* leave room for trailing '\0' */
+ /* Force ungetc leftover to call apr_file_read. */
+ if (thefile->bufpos < thefile->dataRead &&
+ thefile->ungetchar == -1) {
+ *str = thefile->buffer[thefile->bufpos++];
+ }
+ else {
+ nbytes = 1;
+ rv = apr_file_read(thefile, str, &nbytes);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ }
+ if (*str == '\n') {
+ ++str;
+ break;
+ }
+ ++str;
+ }
+
+#if APR_HAS_THREADS
+ if (thefile->thlock) {
+ apr_thread_mutex_unlock(thefile->thlock);
+ }
+#endif
+ }
+ else {
+ while (str < final) { /* leave room for trailing '\0' */
+ nbytes = 1;
+ rv = apr_file_read(thefile, str, &nbytes);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ if (*str == '\n') {
+ ++str;
+ break;
+ }
++str;
- break;
}
- ++str;
}
+
/* We must store a terminating '\0' if we've stored any chars. We can
* get away with storing it if we hit an error first.
*/
diff --git a/file_io/win32/dir.c b/file_io/win32/dir.c
index ab2d08047..19fe15e8c 100644
--- a/file_io/win32/dir.c
+++ b/file_io/win32/dir.c
@@ -49,7 +49,7 @@ APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new, const char *dirname,
{
apr_status_t rv;
- int len = strlen(dirname);
+ apr_size_t len = strlen(dirname);
(*new) = apr_pcalloc(pool, sizeof(apr_dir_t));
/* Leave room here to add and pop the '*' wildcard for FindFirstFile
* and double-null terminate so we have one character to change.
@@ -243,7 +243,7 @@ APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
#else
char fspec[APR_PATH_MAX];
#endif
- int dirlen = strlen(thedir->dirname);
+ apr_size_t dirlen = strlen(thedir->dirname);
if (dirlen >= sizeof(fspec))
dirlen = sizeof(fspec) - 1;
apr_cpystrn(fspec, thedir->dirname, sizeof(fspec));
diff --git a/file_io/win32/filedup.c b/file_io/win32/filedup.c
index 57c57ea02..63aa25089 100644
--- a/file_io/win32/filedup.c
+++ b/file_io/win32/filedup.c
@@ -44,6 +44,13 @@ APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
(*new_file)->buffered = FALSE;
(*new_file)->ungetchar = old_file->ungetchar;
+#if APR_HAS_THREADS
+ if (old_file->mutex) {
+ apr_thread_mutex_create(&((*new_file)->mutex),
+ APR_THREAD_MUTEX_DEFAULT, p);
+ }
+#endif
+
apr_pool_cleanup_register((*new_file)->pool, (void *)(*new_file), file_cleanup,
apr_pool_cleanup_null);
@@ -118,6 +125,13 @@ APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t *new_file,
new_file->buffered = FALSE;
new_file->ungetchar = old_file->ungetchar;
+#if APR_HAS_THREADS
+ if (old_file->mutex) {
+ apr_thread_mutex_create(&(new_file->mutex),
+ APR_THREAD_MUTEX_DEFAULT, p);
+ }
+#endif
+
return APR_SUCCESS;
#endif /* !defined(_WIN32_WCE) */
}
diff --git a/file_io/win32/open.c b/file_io/win32/open.c
index e937801f8..1b950fc21 100644
--- a/file_io/win32/open.c
+++ b/file_io/win32/open.c
@@ -47,7 +47,7 @@ apr_status_t utf8_to_unicode_path(apr_wchar_t* retstr, apr_size_t retlen,
* Note that the \\?\ form only works for local drive paths, and
* \\?\UNC\ is needed UNC paths.
*/
- int srcremains = strlen(srcstr) + 1;
+ apr_size_t srcremains = strlen(srcstr) + 1;
apr_wchar_t *t = retstr;
apr_status_t rv;
@@ -101,7 +101,7 @@ apr_status_t unicode_to_utf8_path(char* retstr, apr_size_t retlen,
* then transform \\'s back into /'s since the \\?\ form never
* allows '/' path seperators, and APR always uses '/'s.
*/
- int srcremains = wcslen(srcstr) + 1;
+ apr_size_t srcremains = wcslen(srcstr) + 1;
apr_status_t rv;
char *t = retstr;
if (srcstr[0] == L'\\' && srcstr[1] == L'\\' &&
@@ -324,6 +324,8 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname,
else {
return APR_EACCES;
}
+ if (flag & APR_READCONTROL)
+ oflags |= READ_CONTROL;
}
if (flag & APR_XTHREAD) {
diff --git a/file_io/win32/readwrite.c b/file_io/win32/readwrite.c
index b8a5e4be8..7a5931387 100644
--- a/file_io/win32/readwrite.c
+++ b/file_io/win32/readwrite.c
@@ -27,9 +27,10 @@
* read_with_timeout()
* Uses async i/o to emulate unix non-blocking i/o with timeouts.
*/
-static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len, apr_size_t *nbytes)
+static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len_in, apr_size_t *nbytes)
{
apr_status_t rv;
+ DWORD len = (DWORD)len_in;
*nbytes = 0;
/* Handle the zero timeout non-blocking case */
@@ -68,7 +69,8 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le
file->pOverlapped->OffsetHigh = (DWORD)(file->filePtr >> 32);
}
- rv = ReadFile(file->filehand, buf, len, nbytes, file->pOverlapped);
+ *nbytes = 0;
+ rv = ReadFile(file->filehand, buf, len, (LPDWORD)nbytes, file->pOverlapped);
if (!rv) {
rv = apr_get_os_error();
@@ -85,7 +87,7 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le
switch (rv) {
case WAIT_OBJECT_0:
GetOverlappedResult(file->filehand, file->pOverlapped,
- nbytes, TRUE);
+ (LPDWORD)nbytes, TRUE);
rv = APR_SUCCESS;
break;
case WAIT_TIMEOUT:
@@ -286,7 +288,7 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a
thefile->pOverlapped->Offset = (DWORD)thefile->filePtr;
thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >> 32);
}
- rv = WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
+ rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
thefile->pOverlapped);
if (thefile->append) {
apr_file_unlock(thefile);
@@ -294,7 +296,7 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a
}
}
else {
- rv = WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
+ rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
thefile->pOverlapped);
}
if (rv) {
@@ -309,7 +311,7 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a
rv = WaitForSingleObject(thefile->pOverlapped->hEvent, INFINITE);
switch (rv) {
case WAIT_OBJECT_0:
- GetOverlappedResult(thefile->filehand, thefile->pOverlapped, nbytes, TRUE);
+ GetOverlappedResult(thefile->filehand, thefile->pOverlapped, (LPDWORD)nbytes, TRUE);
rv = APR_SUCCESS;
break;
case WAIT_TIMEOUT:
@@ -343,7 +345,7 @@ APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
{
apr_status_t rv = APR_SUCCESS;
apr_size_t i;
- DWORD bwrote = 0;
+ apr_size_t bwrote = 0;
char *buf;
*nbytes = 0;
@@ -361,7 +363,7 @@ APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
{
- DWORD len = 1;
+ apr_size_t len = 1;
return apr_file_write(thefile, &ch, &len);
}
@@ -375,7 +377,7 @@ APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
{
apr_status_t rc;
- int bread;
+ apr_size_t bread;
bread = 1;
rc = apr_file_read(thefile, ch, &bread);
@@ -393,7 +395,7 @@ APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
{
- DWORD len = strlen(str);
+ apr_size_t len = strlen(str);
return apr_file_write(thefile, str, &len);
}
@@ -431,13 +433,34 @@ APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile)
APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile)
{
if (thefile->buffered) {
- DWORD written = 0;
+ DWORD numbytes, written = 0;
apr_status_t rc = 0;
+ char *buffer;
+ apr_size_t bytesleft;
if (thefile->direction == 1 && thefile->bufpos) {
- if (!WriteFile(thefile->filehand, thefile->buffer, thefile->bufpos, &written, NULL))
- rc = apr_get_os_error();
- thefile->filePtr += written;
+ buffer = thefile->buffer;
+ bytesleft = thefile->bufpos;
+
+ do {
+ if (bytesleft > APR_DWORD_MAX) {
+ numbytes = APR_DWORD_MAX;
+ }
+ else {
+ numbytes = (DWORD)bytesleft;
+ }
+
+ if (!WriteFile(thefile->filehand, buffer, numbytes, &written, NULL)) {
+ rc = apr_get_os_error();
+ thefile->filePtr += written;
+ break;
+ }
+
+ thefile->filePtr += written;
+ bytesleft -= written;
+ buffer += written;
+
+ } while (bytesleft > 0);
if (rc == 0)
thefile->bufpos = 0;