bjh 99/10/19 08:24:22
Modified: src/lib/apr/file_io/os2 open.c pipe.c readwrite.c seek.c
Log:
OS/2: First take at adding buffered file I/O support. Only reads tested so
far.
Revision Changes Path
1.9 +11 -0 apache-2.0/src/lib/apr/file_io/os2/open.c
Index: open.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/open.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- open.c 1999/10/18 14:55:19 1.8
+++ open.c 1999/10/19 15:24:19 1.9
@@ -83,6 +83,7 @@
dafile->isopen = FALSE;
dafile->validstatus = FALSE;
dafile->eof_hit = FALSE;
+ dafile->buffer = NULL;
if ((flag & APR_READ) && (flag & APR_WRITE)) {
mflags |= OPEN_ACCESS_READWRITE;
@@ -131,6 +132,14 @@
dafile->isopen = TRUE;
dafile->fname = ap_pstrdup(cntxt, fname);
+ dafile->filePtr = 0;
+ dafile->bufpos = 0;
+ dafile->dataRead = 0;
+ dafile->direction = 0;
+
+ if (dafile->buffered)
+ dafile->buffer = ap_palloc(cntxt, APR_FILE_BUFSIZE);
+
ap_register_cleanup(dafile->cntxt, dafile, file_cleanup,
ap_null_cleanup);
return APR_SUCCESS;
}
@@ -185,6 +194,8 @@
(*file)->cntxt = cont;
}
(*file)->filedes = *dafile;
+ (*file)->isopen = TRUE;
+ (*file)->buffered = FALSE;
return APR_SUCCESS;
}
1.5 +2 -0 apache-2.0/src/lib/apr/file_io/os2/pipe.c
Index: pipe.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/pipe.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- pipe.c 1999/10/12 06:14:41 1.4
+++ pipe.c 1999/10/19 15:24:19 1.5
@@ -75,6 +75,7 @@
(*in)->filedes = filedes[0];
(*in)->fname = ap_pstrdup(cont, "PIPE");
(*in)->isopen = TRUE;
+ (*in)->buffered = FALSE;
ap_register_cleanup(cont, *in, file_cleanup, ap_null_cleanup);
(*out) = (struct file_t *)ap_palloc(cont, sizeof(struct file_t));
@@ -82,6 +83,7 @@
(*out)->filedes = filedes[1];
(*out)->fname = ap_pstrdup(cont, "PIPE");
(*out)->isopen = TRUE;
+ (*out)->buffered = FALSE;
ap_register_cleanup(cont, *out, file_cleanup, ap_null_cleanup);
return APR_SUCCESS;
1.5 +114 -28 apache-2.0/src/lib/apr/file_io/os2/readwrite.c
Index: readwrite.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/readwrite.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- readwrite.c 1999/10/19 01:59:48 1.4
+++ readwrite.c 1999/10/19 15:24:19 1.5
@@ -62,35 +62,77 @@
ap_status_t ap_read(struct file_t *thefile, void *buf, ap_ssize_t *nbytes)
{
- ULONG rc;
+ ULONG rc = 0;
ULONG bytesread;
if (!thefile->isopen) {
*nbytes = 0;
return APR_EBADF;
}
-
- rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
- if (rc) {
- *nbytes = 0;
+ if (thefile->buffered) {
+ char *pos = (char *)buf;
+ ULONG blocksize;
+ ULONG size = *nbytes;
+
+ if (thefile->direction == 1) {
+ ap_flush(thefile);
+ thefile->bufpos = 0;
+ thefile->direction = 0;
+ thefile->dataRead = 0;
+ }
+
+ while (rc == 0 && size > 0) {
+ if (thefile->bufpos >= thefile->dataRead) {
+ rc = DosRead(thefile->filedes, thefile->buffer,
APR_FILE_BUFSIZE, &thefile->dataRead );
+ if (thefile->dataRead == 0)
+ break;
+ 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;
+
+ // if an error occurred report it
+ // if we read some data but hit EOF before reading 'size' bytes,
return Ok (0)
+ // if we hit EOF with no data read, return -1
+ if (size && rc == 0 && pos == (char *)buf) {
+ thefile->eof_hit = TRUE;
+ *_errno() = APR_EOF;
+ return APR_EOF;
+ }
return os2errno(rc);
+ } else {
+ rc = DosRead(thefile->filedes, buf, *nbytes, &bytesread);
+
+ if (rc) {
+ *nbytes = 0;
+ return os2errno(rc);
+ }
+
+ *nbytes = bytesread;
+
+ if (bytesread == 0) {
+ thefile->eof_hit = TRUE;
+ return APR_EOF;
+ }
+
+ return APR_SUCCESS;
}
-
- if (bytesread == 0) {
- thefile->eof_hit = TRUE;
- return APR_EOF;
- }
-
- *nbytes = bytesread;
- return APR_SUCCESS;
}
ap_status_t ap_write(struct file_t *thefile, void *buf, ap_ssize_t *nbytes)
{
- ULONG rc;
+ ULONG rc = 0;
ULONG byteswritten;
if (!thefile->isopen) {
@@ -98,16 +140,44 @@
return APR_EBADF;
}
- rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
+ if (thefile->buffered) {
+ char *pos = (char *)buf;
+ int blocksize;
+ int size = *nbytes;
+
+ 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
+ ap_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;
+ }
- if (rc) {
- *nbytes = 0;
return os2errno(rc);
+ } else {
+ rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
+
+ if (rc) {
+ *nbytes = 0;
+ return os2errno(rc);
+ }
+
+ *nbytes = byteswritten;
+ thefile->validstatus = FALSE;
+ return APR_SUCCESS;
}
-
- *nbytes = byteswritten;
- thefile->validstatus = FALSE;
- return APR_SUCCESS;
}
@@ -176,16 +246,17 @@
ap_status_t ap_getc(char *ch, ap_file_t *thefile)
{
ULONG rc;
- ULONG bytesread;
+ int bytesread;
if (!thefile->isopen) {
return APR_EBADF;
}
- rc = DosRead(thefile->filedes, ch, 1, &bytesread);
+ bytesread = 1;
+ rc = ap_read(thefile, ch, &bytesread);
if (rc) {
- return os2errno(rc);
+ return rc;
}
if (bytesread == 0) {
@@ -210,10 +281,25 @@
ap_status_t ap_flush(ap_file_t *thefile)
{
- /* There isn't anything to do if we aren't buffering the output
- * so just return success.
- */
- return APR_SUCCESS;
+ 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 os2errno(rc);
+ } else {
+ /* There isn't anything to do if we aren't buffering the output
+ * so just return success.
+ */
+ return APR_SUCCESS;
+ }
}
1.2 +58 -6 apache-2.0/src/lib/apr/file_io/os2/seek.c
Index: seek.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/seek.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- seek.c 1999/08/17 15:59:36 1.1
+++ seek.c 1999/10/19 15:24:20 1.2
@@ -64,25 +64,77 @@
int os2errno( ULONG oserror );
+
+
+static ap_status_t setptr(struct file_t *thefile, unsigned long pos )
+{
+ long newbufpos;
+ ULONG rc;
+
+ if (thefile->direction == 1) {
+ ap_flush(thefile);
+ thefile->bufpos = thefile->direction = thefile->dataRead = 0;
+ }
+
+ newbufpos = pos - (thefile->filePtr - thefile->dataRead);
+ if (newbufpos >= 0 && newbufpos <= thefile->dataRead) {
+ thefile->bufpos = newbufpos;
+ rc = 0;
+ } else {
+ rc = DosSetFilePtr(thefile->filedes, pos, FILE_BEGIN,
&thefile->filePtr );
+
+ if ( !rc )
+ thefile->bufpos = thefile->dataRead = 0;
+ }
+
+ return os2errno(rc);
+}
+
+
+
ap_status_t ap_seek(struct file_t *thefile, ap_seek_where_t where, ap_off_t
*offset)
{
if (!thefile->isopen) {
return APR_EBADF;
}
-
- switch (where) {
+
+ if (thefile->buffered) {
+ int rc = EINVAL;
+ ap_ssize_t filesize;
+
+ switch (where) {
+ case APR_SET:
+ rc = setptr(thefile, *offset);
+ break;
+
+ case APR_CUR:
+ rc = setptr(thefile, thefile->filePtr - thefile->dataRead +
thefile->bufpos + *offset);
+ break;
+
+ case APR_END:
+ rc = ap_get_filesize(&filesize, thefile);
+ if (rc == APR_SUCCESS)
+ rc = setptr(thefile, filesize - *offset);
+ break;
+ }
+
+ *offset = thefile->filePtr + thefile->bufpos;
+ return rc;
+ } else {
+ switch (where) {
case APR_SET:
where = FILE_BEGIN;
break;
-
+
case APR_CUR:
where = FILE_CURRENT;
break;
-
+
case APR_END:
where = FILE_END;
break;
+ }
+
+ return os2errno(DosSetFilePtr(thefile->filedes, *offset, where,
(ULONG *)&offset));
}
-
- return os2errno(DosSetFilePtr(thefile->filedes, *offset, where, (ULONG
*)&offset));
}