SCP: Avoid seeking on attached sequential devices on non seekable files
As reported on #982
This commit is contained in:
parent
c32b3ab054
commit
852c0bc1bc
5 changed files with 52 additions and 13 deletions
3
scp.c
3
scp.c
|
@ -8736,7 +8736,8 @@ for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { /* reposition all */
|
||||||
for (j = 0; j < dptr->numunits; j++) { /* seq devices */
|
for (j = 0; j < dptr->numunits; j++) { /* seq devices */
|
||||||
uptr = dptr->units + j;
|
uptr = dptr->units + j;
|
||||||
if ((uptr->flags & (UNIT_ATT + UNIT_SEQ)) == (UNIT_ATT + UNIT_SEQ))
|
if ((uptr->flags & (UNIT_ATT + UNIT_SEQ)) == (UNIT_ATT + UNIT_SEQ))
|
||||||
if (sim_fseek (uptr->fileref, uptr->pos, SEEK_SET))
|
if (sim_can_seek (uptr->fileref) &&
|
||||||
|
(0 != sim_fseek (uptr->fileref, uptr->pos, SEEK_SET)))
|
||||||
return sim_messagef (SCPE_IERR, "Can't seek to %u in %s for %s\n", (unsigned)uptr->pos, uptr->filename, sim_uname (uptr));
|
return sim_messagef (SCPE_IERR, "Can't seek to %u in %s for %s\n", (unsigned)uptr->pos, uptr->filename, sim_uname (uptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ static t_stat sim_os_ttinit (void);
|
||||||
static t_stat sim_os_ttrun (void);
|
static t_stat sim_os_ttrun (void);
|
||||||
static t_stat sim_os_ttcmd (void);
|
static t_stat sim_os_ttcmd (void);
|
||||||
static t_stat sim_os_ttclose (void);
|
static t_stat sim_os_ttclose (void);
|
||||||
static t_bool sim_os_ttisatty (void);
|
static t_bool sim_os_fd_isatty (int fd);
|
||||||
|
|
||||||
static t_stat sim_set_rem_telnet (int32 flag, CONST char *cptr);
|
static t_stat sim_set_rem_telnet (int32 flag, CONST char *cptr);
|
||||||
static t_stat sim_set_rem_bufsize (int32 flag, CONST char *cptr);
|
static t_stat sim_set_rem_bufsize (int32 flag, CONST char *cptr);
|
||||||
|
@ -3256,10 +3256,14 @@ t_bool sim_ttisatty (void)
|
||||||
static int answer = -1;
|
static int answer = -1;
|
||||||
|
|
||||||
if (answer == -1)
|
if (answer == -1)
|
||||||
answer = sim_os_ttisatty ();
|
answer = sim_os_fd_isatty (0);
|
||||||
return (t_bool)answer;
|
return (t_bool)answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_bool sim_fd_isatty (int fd)
|
||||||
|
{
|
||||||
|
return sim_os_fd_isatty (fd);
|
||||||
|
}
|
||||||
|
|
||||||
/* Platform specific routine definitions */
|
/* Platform specific routine definitions */
|
||||||
|
|
||||||
|
@ -3356,9 +3360,9 @@ sys$dassgn (tty_chan);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_bool sim_os_ttisatty (void)
|
static t_bool sim_os_fd_isatty (int fd)
|
||||||
{
|
{
|
||||||
return isatty (fileno (stdin));
|
return isatty (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat sim_os_poll_kbd_data (void)
|
static t_stat sim_os_poll_kbd_data (void)
|
||||||
|
@ -3446,8 +3450,10 @@ return SCPE_OK;
|
||||||
#define RAW_MODE 0
|
#define RAW_MODE 0
|
||||||
static HANDLE std_input;
|
static HANDLE std_input;
|
||||||
static HANDLE std_output;
|
static HANDLE std_output;
|
||||||
|
static HANDLE std_error;
|
||||||
static DWORD saved_input_mode;
|
static DWORD saved_input_mode;
|
||||||
static DWORD saved_output_mode;
|
static DWORD saved_output_mode;
|
||||||
|
static DWORD saved_error_mode;
|
||||||
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
|
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||||
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
||||||
#endif
|
#endif
|
||||||
|
@ -3495,12 +3501,16 @@ sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_ttinit()\n");
|
||||||
SetConsoleCtrlHandler( ControlHandler, TRUE );
|
SetConsoleCtrlHandler( ControlHandler, TRUE );
|
||||||
std_input = GetStdHandle (STD_INPUT_HANDLE);
|
std_input = GetStdHandle (STD_INPUT_HANDLE);
|
||||||
std_output = GetStdHandle (STD_OUTPUT_HANDLE);
|
std_output = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||||
|
std_error = GetStdHandle (STD_ERROR_HANDLE);
|
||||||
if ((std_input) && /* Not Background process? */
|
if ((std_input) && /* Not Background process? */
|
||||||
(std_input != INVALID_HANDLE_VALUE))
|
(std_input != INVALID_HANDLE_VALUE))
|
||||||
GetConsoleMode (std_input, &saved_input_mode); /* Save Input Mode */
|
GetConsoleMode (std_input, &saved_input_mode); /* Save Input Mode */
|
||||||
if ((std_output) && /* Not Background process? */
|
if ((std_output) && /* Not Background process? */
|
||||||
(std_output != INVALID_HANDLE_VALUE))
|
(std_output != INVALID_HANDLE_VALUE))
|
||||||
GetConsoleMode (std_output, &saved_output_mode); /* Save Output Mode */
|
GetConsoleMode (std_output, &saved_output_mode); /* Save Output Mode */
|
||||||
|
if ((std_error) && /* Not Background process? */
|
||||||
|
(std_error != INVALID_HANDLE_VALUE))
|
||||||
|
GetConsoleMode (std_error, &saved_error_mode); /* Save Output Mode */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3557,11 +3567,26 @@ static t_stat sim_os_ttclose (void)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_bool sim_os_ttisatty (void)
|
static t_bool sim_os_fd_isatty (int fd)
|
||||||
{
|
{
|
||||||
DWORD Mode;
|
DWORD Mode;
|
||||||
|
HANDLE handle;
|
||||||
|
|
||||||
return (std_input) && (std_input != INVALID_HANDLE_VALUE) && GetConsoleMode (std_input, &Mode);
|
switch (fd) {
|
||||||
|
case 0:
|
||||||
|
handle = std_input;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
handle = std_output;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
handle = std_error;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (handle) && (handle != INVALID_HANDLE_VALUE) && GetConsoleMode (handle, &Mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat sim_os_poll_kbd (void)
|
static t_stat sim_os_poll_kbd (void)
|
||||||
|
@ -3712,7 +3737,7 @@ static t_stat sim_os_ttclose (void)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_bool sim_os_ttisatty (void)
|
static t_bool sim_os_fd_isatty (int fd)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -3924,7 +3949,7 @@ static t_stat sim_os_ttclose (void)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_bool sim_os_ttisatty (void)
|
static t_bool sim_os_fd_isatty (int fd)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -4067,9 +4092,9 @@ static t_stat sim_os_ttclose (void)
|
||||||
return sim_ttcmd ();
|
return sim_ttcmd ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_bool sim_os_ttisatty (void)
|
static t_bool sim_os_fd_isatty (int fd)
|
||||||
{
|
{
|
||||||
return isatty (fileno (stdin));
|
return isatty (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat sim_os_poll_kbd (void)
|
static t_stat sim_os_poll_kbd (void)
|
||||||
|
@ -4241,9 +4266,9 @@ static t_stat sim_os_ttclose (void)
|
||||||
return sim_ttcmd ();
|
return sim_ttcmd ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_bool sim_os_ttisatty (void)
|
static t_bool sim_os_fd_isatty (int fd)
|
||||||
{
|
{
|
||||||
return isatty (fileno (stdin));
|
return isatty (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat sim_os_poll_kbd (void)
|
static t_stat sim_os_poll_kbd (void)
|
||||||
|
|
|
@ -122,6 +122,7 @@ t_stat sim_ttrun (void);
|
||||||
t_stat sim_ttcmd (void);
|
t_stat sim_ttcmd (void);
|
||||||
t_stat sim_ttclose (void);
|
t_stat sim_ttclose (void);
|
||||||
t_bool sim_ttisatty (void);
|
t_bool sim_ttisatty (void);
|
||||||
|
t_bool sim_fd_isatty (int fd);
|
||||||
int32 sim_tt_inpcvt (int32 c, uint32 mode);
|
int32 sim_tt_inpcvt (int32 c, uint32 mode);
|
||||||
int32 sim_tt_outcvt (int32 c, uint32 mode);
|
int32 sim_tt_outcvt (int32 c, uint32 mode);
|
||||||
t_stat sim_tt_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
t_stat sim_tt_set_mode (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||||
|
|
11
sim_fio.c
11
sim_fio.c
|
@ -44,6 +44,7 @@
|
||||||
sim_fwrite - endian independent write (formerly fxwrite)
|
sim_fwrite - endian independent write (formerly fxwrite)
|
||||||
sim_fseek - conditionally extended (>32b) seek (
|
sim_fseek - conditionally extended (>32b) seek (
|
||||||
sim_fseeko - extended seek (>32b if available)
|
sim_fseeko - extended seek (>32b if available)
|
||||||
|
sim_can_seek - test for seekable (regular file)
|
||||||
sim_fsize - get file size
|
sim_fsize - get file size
|
||||||
sim_fsize_name - get file size of named file
|
sim_fsize_name - get file size of named file
|
||||||
sim_fsize_ex - get file size as a t_offset
|
sim_fsize_ex - get file size as a t_offset
|
||||||
|
@ -235,6 +236,16 @@ uint32 sim_fsize (FILE *fp)
|
||||||
return (uint32)(sim_fsize_ex (fp));
|
return (uint32)(sim_fsize_ex (fp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_bool sim_can_seek (FILE *fp)
|
||||||
|
{
|
||||||
|
struct stat statb;
|
||||||
|
|
||||||
|
if ((0 != fstat (fileno (fp), &statb)) ||
|
||||||
|
(0 == (statb.st_mode & S_IFREG)))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* OS-dependent routines */
|
/* OS-dependent routines */
|
||||||
|
|
||||||
/* Optimized file open */
|
/* Optimized file open */
|
||||||
|
|
|
@ -60,6 +60,7 @@ typedef int32 t_offset;
|
||||||
FILE *sim_fopen (const char *file, const char *mode);
|
FILE *sim_fopen (const char *file, const char *mode);
|
||||||
int sim_fseek (FILE *st, t_addr offset, int whence);
|
int sim_fseek (FILE *st, t_addr offset, int whence);
|
||||||
int sim_fseeko (FILE *st, t_offset offset, int whence);
|
int sim_fseeko (FILE *st, t_offset offset, int whence);
|
||||||
|
t_bool sim_can_seek (FILE *st);
|
||||||
int sim_set_fsize (FILE *fptr, t_addr size);
|
int sim_set_fsize (FILE *fptr, t_addr size);
|
||||||
int sim_set_fifo_nonblock (FILE *fptr);
|
int sim_set_fifo_nonblock (FILE *fptr);
|
||||||
size_t sim_fread (void *bptr, size_t size, size_t count, FILE *fptr);
|
size_t sim_fread (void *bptr, size_t size, size_t count, FILE *fptr);
|
||||||
|
|
Loading…
Add table
Reference in a new issue