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)); }