📄 readwrite.c
字号:
DWORD offhi = (DWORD)(offset >> 32);
if (offset != thefile->filePtr)
SetFilePointer(thefile->filehand, offlo, &offhi, FILE_BEGIN);
thefile->bufpos = thefile->dataRead = 0;
thefile->direction = 1;
}
rv = 0;
while (rv == 0 && size > 0) {
if (thefile->bufpos == APR_FILE_BUFSIZE) // write buffer is full
rv = 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 rv;
} else {
if (!thefile->pipe) {
apr_off_t offset = 0;
apr_status_t rc;
if (thefile->append) {
/* apr_file_lock will mutex the file across processes.
* The call to apr_thread_mutex_lock is added to avoid
* a race condition between LockFile and WriteFile
* that occasionally leads to deadlocked threads.
*/
apr_thread_mutex_lock(thefile->mutex);
rc = apr_file_lock(thefile, APR_FLOCK_EXCLUSIVE);
if (rc != APR_SUCCESS) {
apr_thread_mutex_unlock(thefile->mutex);
return rc;
}
rc = apr_file_seek(thefile, APR_END, &offset);
if (rc != APR_SUCCESS) {
apr_thread_mutex_unlock(thefile->mutex);
return rc;
}
}
if (thefile->pOverlapped) {
thefile->pOverlapped->Offset = (DWORD)thefile->filePtr;
thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >> 32);
}
rv = WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
thefile->pOverlapped);
if (thefile->append) {
apr_file_unlock(thefile);
apr_thread_mutex_unlock(thefile->mutex);
}
}
else {
rv = WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
thefile->pOverlapped);
}
if (rv) {
*nbytes = bwrote;
rv = APR_SUCCESS;
}
else {
(*nbytes) = 0;
rv = apr_get_os_error();
if (rv == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) {
/* Wait for the pending i/o (put a timeout here?) */
rv = WaitForSingleObject(thefile->pOverlapped->hEvent, INFINITE);
switch (rv) {
case WAIT_OBJECT_0:
GetOverlappedResult(thefile->filehand, thefile->pOverlapped, nbytes, TRUE);
rv = APR_SUCCESS;
break;
case WAIT_TIMEOUT:
rv = APR_TIMEUP;
break;
case WAIT_FAILED:
rv = apr_get_os_error();
break;
default:
break;
}
if (rv != APR_SUCCESS) {
if (apr_os_level >= APR_WIN_98)
CancelIo(thefile->filehand);
}
}
}
if (rv == APR_SUCCESS && thefile->pOverlapped && !thefile->pipe) {
thefile->filePtr += *nbytes;
}
}
return rv;
}
/* ToDo: Write for it anyway and test the oslevel!
* Too bad WriteFileGather() is not supported on 95&98 (or NT prior to SP2)
*/
APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
const struct iovec *vec,
apr_size_t nvec,
apr_size_t *nbytes)
{
apr_status_t rv = APR_SUCCESS;
apr_size_t i;
DWORD bwrote = 0;
char *buf;
*nbytes = 0;
for (i = 0; i < nvec; i++) {
buf = vec[i].iov_base;
bwrote = vec[i].iov_len;
rv = apr_file_write(thefile, buf, &bwrote);
*nbytes += bwrote;
if (rv != APR_SUCCESS) {
break;
}
}
return rv;
}
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
{
DWORD len = 1;
return apr_file_write(thefile, &ch, &len);
}
APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
{
thefile->ungetchar = (unsigned char) ch;
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
{
apr_status_t rc;
int bread;
bread = 1;
rc = apr_file_read(thefile, ch, &bread);
if (rc) {
return rc;
}
if (bread == 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)
{
DWORD len = strlen(str);
return apr_file_write(thefile, str, &len);
}
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 (readlen != 1) {
rv = APR_EOF;
break;
}
if (str[i] == '\n') {
i++; /* don't clobber this char below */
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(apr_status_t) apr_file_flush(apr_file_t *thefile)
{
if (thefile->buffered) {
DWORD written = 0;
apr_status_t rc = 0;
if (thefile->direction == 1 && thefile->bufpos) {
if (!WriteFile(thefile->filehand, thefile->buffer, thefile->bufpos, &written, NULL))
rc = apr_get_os_error();
thefile->filePtr += written;
if (rc == 0)
thefile->bufpos = 0;
}
return rc;
} else {
FlushFileBuffers(thefile->filehand);
return APR_SUCCESS;
}
}
static int printf_flush(apr_vformatter_buff_t *vbuff)
{
/* I would love to print this stuff out to the file, but I will
* get that working later. :) For now, just return.
*/
return -1;
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -