* Copyright (c) 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)sys_dos.c 1.4 (Berkeley) 6/29/88";
#if !defined(SO_OOBINLINE)
#endif /* !defined(SO_OOBINLINE) */
* MSDOS doesn't have anyway of deciding whether a full-edited line
* is ready to be read in, so we need to do character-by-character
* reads, and then do the editing in the program (in the case where
* we are supporting line-by-line mode).
* The following routines, which are internal to the MSDOS-specific
* code, accomplish this miracle.
#define Hex(c) HEX[(c)&0xff]
static survivorSetup
= 0; /* Do we have ^C hooks in? */
lineend
= 0, /* There is a line terminator */
static char linein
[200], /* Where input line is assembled */
*nextin
= linein
, /* Next input character */
*nextout
= linein
; /* Next character to be consumed */
savedInState
, savedOutState
;
if ((++nextout) >= nextin) { \
nextout = nextin = linein; \
#define characteratatime() (!MODE_LINE(globalmode)) /* one by one */
* Erase the last character on the line.
return; /* Nothing to do */
if (!(isspace(*nextin
) || isprint(*nextin
))) {
* Decide if it's time to send the current line up to the user
if (characteratatime()) {
} else if (nextin
>= (linein
+sizeof linein
)) {
} else if (c
== termFlushChar
) {
} else if ((c
== '\n') || (c
== '\r')) {
/* Otherwise, leave it alone (reset by 'consumechar') */
* OK, what we do here is:
* o If we are echoing, then
* o Look for character erase, line kill characters
* o Echo the character (using '^' if a control character)
* o Put the character in the input buffer
* o Set 'lineend' as necessary
int c
; /* Character to process */
static char literalnextcharacter
= 0;
if (nextin
>= (linein
+sizeof linein
)) {
putchar('\7'); /* Ring bell */
if (MODE_LOCAL_CHARS(globalmode
)) {
/* Look for some special character */
if (!literalnextcharacter
) {
if (c
== termEraseChar
) {
} else if (c
== termKillChar
) {
while (nextin
!= linein
) {
} else if (c
== termLiteralNextChar
) {
literalnextcharacter
= 1;
if (MODE_LOCAL_ECHO(globalmode
)) {
if ((literalnextcharacter
== 0) && ((c
== '\r') || (c
== '\n'))) {
} else if (!isprint(c
) && !isspace(c
)) {
literalnextcharacter
= 0;
#if 1 /* For BIOS variety of calls */
input
= getch(); /* MSC - get console character */
DoNextChar(0x01); /* ^A */
if ((input
= dirconio()) == -1) {
if ((input
&0xff00) == 0x0300) { /* Null */
DoNextChar((input
>>8)&0x7f);
DoNextChar((input
>>8)&0xff);
if (!MODE_COMMAND_LINE(globalmode
)) {
char far
*Bios_Break
= (char far
*) (((long)0x40<<16)|0x71);
signal(SIGINT
, CtrlCInterrupt
);
oldstate
= regs
.h
.dl
&(1<<5); /* Save state */
/* Set correct bits in new mode */
* The MSDOS routines, called from elsewhere.
TerminalAutoFlush() /* MSDOS */
* Flush output to the terminal
TerminalFlushOutput() /* MSDOS */
TerminalNewMode(fd_in
, fd_out
, f
) /* MSDOS */
int fd_in
, fd_out
; /* File descriptors */
static old_1b_offset
= 0, old_1b_segment
= 0;
if (MODE_COMMAND_LINE(f
)) {
if (old_1b_segment
|old_1b_offset
) {
inregs
.x
.dx
= old_1b_offset
;
segregs
.ds
= old_1b_segment
;
intdosx(&inregs
, &inregs
, &segregs
);
old_1b_segment
= old_1b_offset
= 0;
if (setmode(fd_out
, O_TEXT
) == -1) {
ExitPerror("setmode (text)", 1);
(void) dosbinary(fileno(stdout
), 0);
if (setmode(fd_out
, O_TEXT
) == -1) {
ExitPerror("setmode (text)", 1);
(void) dosbinary(fileno(stdin
), 0);
signal(SIGINT
, CtrlCInterrupt
);
if ((old_1b_segment
|old_1b_offset
) == 0) {
void (far
*foo_subr
)() = iret_subr
;
intdosx(&inregs
, &inregs
, &segregs
);
old_1b_segment
= segregs
.es
;
old_1b_offset
= inregs
.x
.bx
;
inregs
.x
.dx
= FP_OFF(foo_subr
);
segregs
.ds
= FP_SEG(foo_subr
);
intdosx(&inregs
, &inregs
, &segregs
);
if (MODE_LOCAL_CHARS(f
)) {
if (setmode(fd_out
, O_TEXT
) == -1) {
ExitPerror("setmode (text)", 1);
(void) dosbinary(fileno(stdout
), 0);
if (setmode(fd_in
, O_TEXT
) == -1) {
ExitPerror("setmode (text)", 1);
(void) dosbinary(fileno(stdin
), 0);
if (setmode(fd_out
, O_BINARY
) == -1) {
ExitPerror("setmode (binary)", 1);
(void) dosbinary(fileno(stdout
), 1);
if (setmode(fd_in
, O_BINARY
) == -1) {
ExitPerror("setmode (binary)", 1);
(void) dosbinary(fileno(stdin
), 1);
TerminalRead(fd
, buffer
, count
)
while (inputExists() && (done
< count
)) {
TerminalSaveState() /* MSDOS */
termLiteralNextChar
= '\26';
savedInState
= dosbinary(fileno(stdin
), 0);
savedOutState
= dosbinary(fileno(stdout
), 0);
TerminalSpecialChars(c
) /* MSDOS */
TerminalRestoreState() /* MSDOS */
(void) dosbinary(fileno(stdin
), savedInState
);
(void) dosbinary(fileno(stdout
), savedOutState
);
TerminalWrite(fd
, buffer
, count
) /* MSDOS */
return fwrite(buffer
, sizeof (char), count
, stdout
); /* XXX */
NetNonblockingIO(fd
, onoff
) /* MSDOS */
if (SetSockOpt(fd
, SOL_SOCKET
, SO_NONBLOCKING
, onoff
)) {
perror("setsockop (SO_NONBLOCKING) ");
ExitString(stderr
, "exiting\n", 1);
NetSetPgrp(fd
) /* MSDOS */
#endif /* defined(MSDOS) */