fix writing too much at once to Windows console or file

svn: r856
This commit is contained in:
Matthew Flatt 2005-09-15 15:45:35 +00:00
parent edfd2a4dd3
commit b57b871b79
2 changed files with 42 additions and 21 deletions

View File

@ -4687,7 +4687,6 @@ static Scheme_Object *make_directory(int argc, Scheme_Object *argv[])
filename[--len] = 0; filename[--len] = 0;
} }
while (1) { while (1) {
if (!MSC_W_IZE(mkdir)(MSC_WIDE_PATH(filename) if (!MSC_W_IZE(mkdir)(MSC_WIDE_PATH(filename)
# ifndef MKDIR_NO_MODE_FLAG # ifndef MKDIR_NO_MODE_FLAG

View File

@ -5535,21 +5535,40 @@ static long flush_fd(Scheme_Output_Port *op,
} else } else
orig_len = 0; /* not used */ orig_len = 0; /* not used */
if (WriteFile((HANDLE)fop->fd, bufstr XFORM_OK_PLUS offset, buflen - offset, &winwrote, NULL)) { /* Write bytes. If we try to write too much at once, the result
if (fop->textmode) { is ERROR_NOT_ENOUGH_MEMORY (as opposed to a partial write). */
if (winwrote != buflen) { {
/* Trouble! This shouldn't happen. We pick an random error msg. */ int ok;
errsaved = ERROR_NEGATIVE_SEEK; long towrite = buflen - offset;
len = -1;
} else { while (1) {
len = orig_len; ok = WriteFile((HANDLE)fop->fd, bufstr XFORM_OK_PLUS offset, towrite, &winwrote, NULL);
buflen = orig_len; /* so we don't loop! */ if (!ok)
} errsaved = GetLastError();
} else
len = winwrote; if (!ok && (errsaved == ERROR_NOT_ENOUGH_MEMORY)) {
} else { towrite = towrite >> 1;
errsaved = GetLastError(); if (!towrite)
len = -1; break;
} else
break;
}
if (ok) {
if (fop->textmode) {
if (winwrote != buflen) {
/* Trouble! This shouldn't happen. We pick an random error msg. */
errsaved = ERROR_NEGATIVE_SEEK;
len = -1;
} else {
len = orig_len;
buflen = orig_len; /* so we don't loop! */
}
} else
len = winwrote;
} else {
len = -1;
}
} }
} else { } else {
errsaved = 0; errsaved = 0;
@ -5601,16 +5620,21 @@ static long flush_fd(Scheme_Output_Port *op,
is not partial writes, but giving up entirely when is not partial writes, but giving up entirely when
the other end isn't being read. In other words, if we the other end isn't being read. In other words, if we
try to write too much and nothing is being pulled try to write too much and nothing is being pulled
from the pipe, winwrote will be set to 0. Account for from the pipe, winwrote will be set to 0. Also, if
this by trying to write less each iteration when the we try to write too much at once, the result is a
ERROR_NOT_ENOUGH_MEMORY error. Account for these
behaviors by trying to write less each iteration when the
write fails. (Yuck.) */ write fails. (Yuck.) */
while (1) { while (1) {
GetNamedPipeHandleState((HANDLE)fop->fd, &old, NULL, NULL, NULL, NULL, 0); GetNamedPipeHandleState((HANDLE)fop->fd, &old, NULL, NULL, NULL, NULL, 0);
SetNamedPipeHandleState((HANDLE)fop->fd, &nonblock, NULL, NULL); SetNamedPipeHandleState((HANDLE)fop->fd, &nonblock, NULL, NULL);
ok = WriteFile((HANDLE)fop->fd, bufstr XFORM_OK_PLUS offset, towrite, &winwrote, NULL); ok = WriteFile((HANDLE)fop->fd, bufstr XFORM_OK_PLUS offset, towrite, &winwrote, NULL);
if (!ok)
errsaved = GetLastError();
SetNamedPipeHandleState((HANDLE)fop->fd, &old, NULL, NULL); SetNamedPipeHandleState((HANDLE)fop->fd, &old, NULL, NULL);
if (ok && !winwrote) { if ((ok && !winwrote)
|| (!ok && (errsaved == ERROR_NOT_ENOUGH_MEMORY))) {
towrite = towrite >> 1; towrite = towrite >> 1;
if (!towrite) { if (!towrite) {
break; break;
@ -5630,8 +5654,6 @@ static long flush_fd(Scheme_Output_Port *op,
} else { } else {
len = winwrote; len = winwrote;
} }
} else {
errsaved = GetLastError();
} }
} else } else
full_write_buffer = 0; /* and create the writer thread... */ full_write_buffer = 0; /* and create the writer thread... */