windows: avoid SetFilePointer() on unsupported file-stream types
Closes PR 12339
This commit is contained in:
parent
5adc74fdf0
commit
291a18b045
|
@ -4992,12 +4992,22 @@ Scheme_Object *scheme_open_output_file_with_mode(const char *name, const char *w
|
||||||
return scheme_do_open_output_file((char *)who, 0, 3, a, 0, 0, NULL, NULL);
|
return scheme_do_open_output_file((char *)who, 0, 3, a, 0, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WINDOWS_FILE_HANDLES
|
||||||
|
static int win_seekable(int fd)
|
||||||
|
{
|
||||||
|
/* SetFilePointer() requires " a file stored on a seeking device".
|
||||||
|
I'm not sure how to test that, so we approximate as "regular
|
||||||
|
file". */
|
||||||
|
return GetFileType((HANDLE)fd) == FILE_TYPE_DISK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Scheme_Object *
|
Scheme_Object *
|
||||||
scheme_file_position(int argc, Scheme_Object *argv[])
|
scheme_file_position(int argc, Scheme_Object *argv[])
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
Scheme_Indexed_String *is;
|
Scheme_Indexed_String *is;
|
||||||
int fd;
|
intptr_t fd;
|
||||||
#ifdef MZ_FDS
|
#ifdef MZ_FDS
|
||||||
int had_fd;
|
int had_fd;
|
||||||
#endif
|
#endif
|
||||||
|
@ -5118,13 +5128,14 @@ scheme_file_position(int argc, Scheme_Object *argv[])
|
||||||
#ifdef MZ_FDS
|
#ifdef MZ_FDS
|
||||||
} else if (had_fd) {
|
} else if (had_fd) {
|
||||||
intptr_t lv;
|
intptr_t lv;
|
||||||
|
int errid = 0;
|
||||||
|
|
||||||
if (!SCHEME_INPUT_PORTP(argv[0])) {
|
if (!SCHEME_INPUT_PORTP(argv[0])) {
|
||||||
flush_fd(scheme_output_port_record(argv[0]), NULL, 0, 0, 0, 0);
|
flush_fd(scheme_output_port_record(argv[0]), NULL, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef WINDOWS_FILE_HANDLES
|
# ifdef WINDOWS_FILE_HANDLES
|
||||||
{
|
if (win_seekable(fd)) {
|
||||||
DWORD r;
|
DWORD r;
|
||||||
LONG lo_w, hi_w;
|
LONG lo_w, hi_w;
|
||||||
lo_w = (LONG)(nll & 0xFFFFFFFF);
|
lo_w = (LONG)(nll & 0xFFFFFFFF);
|
||||||
|
@ -5132,24 +5143,24 @@ scheme_file_position(int argc, Scheme_Object *argv[])
|
||||||
r = SetFilePointer((HANDLE)fd, lo_w, &hi_w,
|
r = SetFilePointer((HANDLE)fd, lo_w, &hi_w,
|
||||||
((whence == SEEK_SET) ? FILE_BEGIN : FILE_END));
|
((whence == SEEK_SET) ? FILE_BEGIN : FILE_END));
|
||||||
if ((r == INVALID_SET_FILE_POINTER)
|
if ((r == INVALID_SET_FILE_POINTER)
|
||||||
&& GetLastError() != NO_ERROR)
|
&& GetLastError() != NO_ERROR) {
|
||||||
|
errid = GetLastError();
|
||||||
lv = -1;
|
lv = -1;
|
||||||
else
|
} else
|
||||||
lv = 0;
|
lv = 0;
|
||||||
|
} else {
|
||||||
|
lv = -1;
|
||||||
|
errid = ERROR_UNSUPPORTED_TYPE;
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
lv = BIG_OFF_T_IZE(lseek)(fd, nll, whence);
|
lv = BIG_OFF_T_IZE(lseek)(fd, nll, whence);
|
||||||
|
if (lv < 0) errid = errno;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (lv < 0) {
|
if (lv < 0) {
|
||||||
# ifdef WINDOWS_FILE_HANDLES
|
|
||||||
int errid;
|
|
||||||
errid = GetLastError();
|
|
||||||
errno = errid;
|
|
||||||
# endif
|
|
||||||
scheme_raise_exn(MZEXN_FAIL_FILESYSTEM,
|
scheme_raise_exn(MZEXN_FAIL_FILESYSTEM,
|
||||||
"file-position: position change failed on stream (" FILENAME_EXN_E ")",
|
"file-position: position change failed on stream (" FILENAME_EXN_E ")",
|
||||||
errno);
|
errid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SCHEME_INPUT_PORTP(argv[0])) {
|
if (SCHEME_INPUT_PORTP(argv[0])) {
|
||||||
|
@ -5231,7 +5242,7 @@ scheme_file_position(int argc, Scheme_Object *argv[])
|
||||||
#ifdef MZ_FDS
|
#ifdef MZ_FDS
|
||||||
} else if (had_fd) {
|
} else if (had_fd) {
|
||||||
# ifdef WINDOWS_FILE_HANDLES
|
# ifdef WINDOWS_FILE_HANDLES
|
||||||
{
|
if (win_seekable(fd)) {
|
||||||
DWORD lo_w, hi_w;
|
DWORD lo_w, hi_w;
|
||||||
hi_w = 0;
|
hi_w = 0;
|
||||||
lo_w = SetFilePointer((HANDLE)fd, 0, &hi_w, FILE_CURRENT);
|
lo_w = SetFilePointer((HANDLE)fd, 0, &hi_w, FILE_CURRENT);
|
||||||
|
@ -5240,7 +5251,8 @@ scheme_file_position(int argc, Scheme_Object *argv[])
|
||||||
pll = -1;
|
pll = -1;
|
||||||
else
|
else
|
||||||
pll = ((mzlonglong)hi_w << 32) | lo_w;
|
pll = ((mzlonglong)hi_w << 32) | lo_w;
|
||||||
}
|
} else
|
||||||
|
pll = -1;
|
||||||
# else
|
# else
|
||||||
pll = BIG_OFF_T_IZE(lseek)(fd, 0, 1);
|
pll = BIG_OFF_T_IZE(lseek)(fd, 0, 1);
|
||||||
# endif
|
# endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user