plat/msdos86: add isatty( ), _setmode( ), read( ), write( )
This commit is contained in:
parent
2dfddf3fa8
commit
0d2b55cd29
22 changed files with 657 additions and 2 deletions
|
@ -73,6 +73,8 @@ name led
|
||||||
{FLOATS?} \
|
{FLOATS?} \
|
||||||
(.e:{TAIL}={PLATFORMDIR}/libem.a \
|
(.e:{TAIL}={PLATFORMDIR}/libem.a \
|
||||||
{PLATFORMDIR}/libsys.a \
|
{PLATFORMDIR}/libsys.a \
|
||||||
|
{PLATFORMDIR}/libc.a \
|
||||||
|
{PLATFORMDIR}/libem.a \
|
||||||
{PLATFORMDIR}/libend.a)
|
{PLATFORMDIR}/libend.a)
|
||||||
linker
|
linker
|
||||||
end
|
end
|
||||||
|
|
12
plat/msdos86/include/ack/plat.h
Normal file
12
plat/msdos86/include/ack/plat.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ACK_PLAT_H
|
||||||
|
#define _ACK_PLAT_H
|
||||||
|
|
||||||
|
#define ACKCONF_WANT_O_TEXT_O_BINARY 1
|
||||||
|
#define ACKCONF_WANT_EMULATED_TIME 0
|
||||||
|
|
||||||
|
#endif
|
24
plat/msdos86/include/build.lua
Normal file
24
plat/msdos86/include/build.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
include("plat/build.lua")
|
||||||
|
|
||||||
|
headermap = {}
|
||||||
|
packagemap = {}
|
||||||
|
|
||||||
|
local function addheader(h)
|
||||||
|
headermap[h] = "./"..h
|
||||||
|
packagemap["$(PLATIND)/msdos86/include/"..h] = "./"..h
|
||||||
|
end
|
||||||
|
|
||||||
|
addheader("ack/plat.h")
|
||||||
|
addheader("sys/types.h")
|
||||||
|
|
||||||
|
acklibrary {
|
||||||
|
name = "headers",
|
||||||
|
hdrs = headermap
|
||||||
|
}
|
||||||
|
|
||||||
|
installable {
|
||||||
|
name = "pkg",
|
||||||
|
map = packagemap
|
||||||
|
}
|
||||||
|
|
||||||
|
|
9
plat/msdos86/include/sys/types.h
Normal file
9
plat/msdos86/include/sys/types.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef _SYS_TYPES_H
|
||||||
|
#define _SYS_TYPES_H
|
||||||
|
|
||||||
|
typedef int pid_t;
|
||||||
|
typedef int mode_t;
|
||||||
|
typedef long time_t;
|
||||||
|
typedef long suseconds_t;
|
||||||
|
|
||||||
|
#endif
|
19
plat/msdos86/libsys/_hol0.s
Normal file
19
plat/msdos86/libsys/_hol0.s
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#
|
||||||
|
! $Source$
|
||||||
|
! $State$
|
||||||
|
! $Revision$
|
||||||
|
|
||||||
|
! Declare segments (the order is important).
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.sect .rom
|
||||||
|
.sect .data
|
||||||
|
.sect .bss
|
||||||
|
|
||||||
|
.sect .bss
|
||||||
|
|
||||||
|
! This data block is used to store information about the current line number
|
||||||
|
! and file.
|
||||||
|
|
||||||
|
.define hol0
|
||||||
|
.comm hol0, 8
|
59
plat/msdos86/libsys/brk.c
Normal file
59
plat/msdos86/libsys/brk.c
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
#define STACK_BUFFER 128 /* number of bytes to leave for stack */
|
||||||
|
|
||||||
|
extern char _end[1];
|
||||||
|
static char* current = _end;
|
||||||
|
|
||||||
|
int brk(void* newend)
|
||||||
|
{
|
||||||
|
/* This variable is used to figure out the current stack pointer,
|
||||||
|
* by taking its address. */
|
||||||
|
char dummy;
|
||||||
|
char* p = newend;
|
||||||
|
|
||||||
|
if ((p > (&dummy - STACK_BUFFER)) ||
|
||||||
|
(p < _end))
|
||||||
|
{
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = p;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* sbrk(int increment)
|
||||||
|
{
|
||||||
|
char* old;
|
||||||
|
char* new;
|
||||||
|
|
||||||
|
if (increment == 0)
|
||||||
|
return current;
|
||||||
|
|
||||||
|
old = current;
|
||||||
|
|
||||||
|
new = old + increment;
|
||||||
|
|
||||||
|
if ((increment > 0) && (new <= old))
|
||||||
|
goto out_of_memory;
|
||||||
|
else if ((increment < 0) && (new >= old))
|
||||||
|
goto out_of_memory;
|
||||||
|
|
||||||
|
if (brk(new) < 0)
|
||||||
|
goto out_of_memory;
|
||||||
|
|
||||||
|
return old;
|
||||||
|
|
||||||
|
out_of_memory:
|
||||||
|
errno = ENOMEM;
|
||||||
|
return OUT_OF_MEMORY;
|
||||||
|
}
|
15
plat/msdos86/libsys/build.lua
Normal file
15
plat/msdos86/libsys/build.lua
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
acklibrary {
|
||||||
|
name = "lib",
|
||||||
|
srcs = {
|
||||||
|
"./*.c",
|
||||||
|
"./*.s",
|
||||||
|
},
|
||||||
|
deps = {
|
||||||
|
"lang/cem/libcc.ansi/headers+headers",
|
||||||
|
"plat/msdos86/include+headers",
|
||||||
|
},
|
||||||
|
vars = {
|
||||||
|
plat = "msdos86"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
14
plat/msdos86/libsys/creat.c
Normal file
14
plat/msdos86/libsys/creat.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
int creat(const char* path, int mode)
|
||||||
|
{
|
||||||
|
return open(path, O_CREAT|O_WRONLY|O_TRUNC, mode);
|
||||||
|
}
|
37
plat/msdos86/libsys/isatty.s
Normal file
37
plat/msdos86/libsys/isatty.s
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#
|
||||||
|
! $Source$
|
||||||
|
! $State$
|
||||||
|
! $Revision$
|
||||||
|
|
||||||
|
! Declare segments (the order is important).
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.sect .rom
|
||||||
|
.sect .data
|
||||||
|
.sect .bss
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
|
||||||
|
! Say whether a given file descriptor number refers to a terminal.
|
||||||
|
|
||||||
|
.define _isatty
|
||||||
|
_isatty:
|
||||||
|
mov bx, sp
|
||||||
|
mov bx, 2(bx)
|
||||||
|
mov ax, 0x4400
|
||||||
|
int 0x21
|
||||||
|
jc error
|
||||||
|
testb dl, dl
|
||||||
|
jz not_tty
|
||||||
|
mov ax, 1
|
||||||
|
ret
|
||||||
|
not_tty:
|
||||||
|
mov (_errno), 25 ! ENOTTY
|
||||||
|
not_tty_2:
|
||||||
|
xor ax, ax
|
||||||
|
ret
|
||||||
|
error:
|
||||||
|
push ax
|
||||||
|
call __sys_seterrno
|
||||||
|
pop cx
|
||||||
|
jmp not_tty_2
|
53
plat/msdos86/libsys/libsys.h
Normal file
53
plat/msdos86/libsys/libsys.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBSYS_H
|
||||||
|
#define LIBSYS_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#define OUT_OF_MEMORY ((void *)-1) /* sbrk returns this on failure */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data structure for remembering whether each file descriptor is open in
|
||||||
|
* text mode (O_TEXT) or binary mode (O_BINARY).
|
||||||
|
*
|
||||||
|
* Currently this is just a simple linked list, where each linked list node
|
||||||
|
* records the modes for 16 file descriptors, in bit vector form (0: text,
|
||||||
|
* 1: binary). In addition, each node also remembers, for each of its file
|
||||||
|
* descriptors, whether an end-of-file (^Z) character was encountered when
|
||||||
|
* reading from it in text mode.
|
||||||
|
*
|
||||||
|
* List nodes are allocated using sbrk() and never freed.
|
||||||
|
*
|
||||||
|
* This scheme should be fast and light enough, as the number of open file
|
||||||
|
* descriptors is expected to be small.
|
||||||
|
*
|
||||||
|
* FIXME: the code for updating this structure is not exactly thread-safe.
|
||||||
|
*/
|
||||||
|
typedef uint16_t _fdvec_t;
|
||||||
|
|
||||||
|
struct _fdmodes {
|
||||||
|
struct _fdmodes *next;
|
||||||
|
int begfd;
|
||||||
|
_fdvec_t modevec, eofvec;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _fdmodes _sys_fdmodes;
|
||||||
|
|
||||||
|
#define _FDVECMASK (sizeof(_fdvec_t) * CHAR_BIT - 1)
|
||||||
|
|
||||||
|
extern int _sys_getmode(int);
|
||||||
|
extern int _sys_setmode(int, int);
|
||||||
|
extern int _sys_iseof(int);
|
||||||
|
extern int _sys_seteof(int, int);
|
||||||
|
extern ssize_t _sys_rawread(int, char *, size_t);
|
||||||
|
extern ssize_t _sys_rawwrite(int, const char *, size_t);
|
||||||
|
extern int _sys_isopen(int);
|
||||||
|
extern int _sys_isreadyr(int);
|
||||||
|
|
||||||
|
#endif
|
77
plat/msdos86/libsys/read.c
Normal file
77
plat/msdos86/libsys/read.c
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
ssize_t read(int fd, void* buffer, size_t count)
|
||||||
|
{
|
||||||
|
char *p, *q;
|
||||||
|
ssize_t r, tot;
|
||||||
|
size_t left;
|
||||||
|
int eof = 0;
|
||||||
|
|
||||||
|
if (!count || _sys_getmode(fd) == O_BINARY)
|
||||||
|
return _sys_rawread(fd, buffer, count);
|
||||||
|
|
||||||
|
if (_sys_iseof(fd))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the file descriptor is an O_TEXT fd, read from it, and then
|
||||||
|
* remove CRs from the input. After removing CRs, if the buffer is
|
||||||
|
* not filled and the fd still has bytes left to read, then keep
|
||||||
|
* reading, and keep removing CRs.
|
||||||
|
*
|
||||||
|
* Also handle end-of-file indicators (^Z). If we see one, move the
|
||||||
|
* file pointer to just before the ^Z. Also set an internal flag
|
||||||
|
* for the fd so that we do not try to read any further (until e.g.
|
||||||
|
* a seek happens).
|
||||||
|
*/
|
||||||
|
p = buffer;
|
||||||
|
tot = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
r = _sys_rawread(fd, p, count - (p - (char *)buffer));
|
||||||
|
if (r <= 0)
|
||||||
|
return tot;
|
||||||
|
|
||||||
|
q = memchr(p, 0x1a, (size_t)r);
|
||||||
|
if (q)
|
||||||
|
{
|
||||||
|
_sys_rawlseek(fd, (off_t)(q - p) - r, SEEK_CUR);
|
||||||
|
r = q - p;
|
||||||
|
eof = 1;
|
||||||
|
_sys_seteof(fd, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
q = memchr(p, '\r', (size_t)r);
|
||||||
|
if (!q)
|
||||||
|
return tot + r;
|
||||||
|
|
||||||
|
tot += q - p;
|
||||||
|
left = r - (q + 1 - p);
|
||||||
|
p = q;
|
||||||
|
++q;
|
||||||
|
|
||||||
|
while (left)
|
||||||
|
{
|
||||||
|
char c = *q++;
|
||||||
|
if (c != '\r')
|
||||||
|
{
|
||||||
|
*p++ = c;
|
||||||
|
++tot;
|
||||||
|
}
|
||||||
|
--left;
|
||||||
|
}
|
||||||
|
} while (tot < count && !eof && _sys_isreadyr(fd));
|
||||||
|
|
||||||
|
return tot;
|
||||||
|
}
|
23
plat/msdos86/libsys/setmode.c
Normal file
23
plat/msdos86/libsys/setmode.c
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
int _setmode(int fd, int mode)
|
||||||
|
{
|
||||||
|
if (mode != O_TEXT && mode != O_BINARY)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!_sys_isopen(fd))
|
||||||
|
{
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return _sys_setmode(fd, mode);
|
||||||
|
}
|
13
plat/msdos86/libsys/sys_fdmodes.c
Normal file
13
plat/msdos86/libsys/sys_fdmodes.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By default, consider all file descriptors, including those for stdin (0),
|
||||||
|
* stdout (1), and stderr (2), as being open in text mode.
|
||||||
|
*/
|
||||||
|
struct _fdmodes _sys_fdmodes = { NULL, 0, 0 };
|
27
plat/msdos86/libsys/sys_getmode.c
Normal file
27
plat/msdos86/libsys/sys_getmode.c
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Say whether a particular fd is currently open in text or binary mode.
|
||||||
|
* Assume that the fd is valid. Return O_TEXT or O_BINARY.
|
||||||
|
*/
|
||||||
|
int _sys_getmode(int fd)
|
||||||
|
{
|
||||||
|
int reqbegfd = fd & ~_FDVECMASK;
|
||||||
|
struct _fdmodes *p = &_sys_fdmodes;
|
||||||
|
_fdvec_t mask;
|
||||||
|
|
||||||
|
while (p->begfd != reqbegfd)
|
||||||
|
{
|
||||||
|
p = p->next;
|
||||||
|
if (!p)
|
||||||
|
return O_TEXT;
|
||||||
|
}
|
||||||
|
mask = (_fdvec_t)1 << (fd & _FDVECMASK);
|
||||||
|
return (p->modevec & mask) ? O_BINARY : O_TEXT;
|
||||||
|
}
|
|
@ -6,8 +6,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "libsys.h"
|
||||||
#define OUT_OF_MEMORY (void*)(-1) /* sbrk returns this on failure */
|
|
||||||
|
|
||||||
struct for_main {
|
struct for_main {
|
||||||
int argc;
|
int argc;
|
||||||
|
|
27
plat/msdos86/libsys/sys_iseof.c
Normal file
27
plat/msdos86/libsys/sys_iseof.c
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Say whether a particular fd is currently open in text mode and has just
|
||||||
|
* hit an MS-DOS end-of-file character (^Z).
|
||||||
|
*/
|
||||||
|
int _sys_iseof(int fd)
|
||||||
|
{
|
||||||
|
int reqbegfd = fd & ~_FDVECMASK;
|
||||||
|
struct _fdmodes *p = &_sys_fdmodes;
|
||||||
|
_fdvec_t mask;
|
||||||
|
|
||||||
|
while (p->begfd != reqbegfd)
|
||||||
|
{
|
||||||
|
p = p->next;
|
||||||
|
if (!p)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
mask = (_fdvec_t)1 << (fd & _FDVECMASK);
|
||||||
|
return p->eofvec & mask;
|
||||||
|
}
|
26
plat/msdos86/libsys/sys_isopen.s
Normal file
26
plat/msdos86/libsys/sys_isopen.s
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#
|
||||||
|
! $Source$
|
||||||
|
! $State$
|
||||||
|
! $Revision$
|
||||||
|
|
||||||
|
! Declare segments (the order is important).
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.sect .rom
|
||||||
|
.sect .data
|
||||||
|
.sect .bss
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
|
||||||
|
! Say whether a given file descriptor number refers to a valid open file
|
||||||
|
! descriptor.
|
||||||
|
|
||||||
|
.define __sys_isopen
|
||||||
|
__sys_isopen:
|
||||||
|
mov bx, sp
|
||||||
|
mov bx, 2(bx)
|
||||||
|
mov ax, 0x4400
|
||||||
|
int 0x21
|
||||||
|
sbb ax, ax
|
||||||
|
inc ax
|
||||||
|
ret
|
28
plat/msdos86/libsys/sys_isreadyr.s
Normal file
28
plat/msdos86/libsys/sys_isreadyr.s
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#
|
||||||
|
! $Source$
|
||||||
|
! $State$
|
||||||
|
! $Revision$
|
||||||
|
|
||||||
|
! Declare segments (the order is important).
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.sect .rom
|
||||||
|
.sect .data
|
||||||
|
.sect .bss
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
|
||||||
|
! Say whether a file descriptor is ready for input, i.e. reading from the
|
||||||
|
! fd will immediately return something.
|
||||||
|
|
||||||
|
.define __sys_isreadyr
|
||||||
|
__sys_isreadyr:
|
||||||
|
mov bx, sp
|
||||||
|
mov ax, 0x4406
|
||||||
|
mov bx, 2(bx)
|
||||||
|
int 0x21
|
||||||
|
jnc ok
|
||||||
|
movb al, 0
|
||||||
|
ok:
|
||||||
|
cbw
|
||||||
|
ret
|
33
plat/msdos86/libsys/sys_rawrw.s
Normal file
33
plat/msdos86/libsys/sys_rawrw.s
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#
|
||||||
|
! $Source$
|
||||||
|
! $State$
|
||||||
|
! $Revision$
|
||||||
|
|
||||||
|
! Declare segments (the order is important).
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
.sect .rom
|
||||||
|
.sect .data
|
||||||
|
.sect .bss
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
|
||||||
|
! Read/write bytes to/to a file descriptor. These routines do not do any
|
||||||
|
! translation between CRLF and LF line endings.
|
||||||
|
!
|
||||||
|
! Note that, for MS-DOS, a raw "write" request of zero bytes will truncate
|
||||||
|
! (or extend) the file to the current file position.
|
||||||
|
|
||||||
|
.define __sys_rawread
|
||||||
|
__sys_rawread:
|
||||||
|
movb ah, 0x3f
|
||||||
|
.data1 0x3d ! eat up the next instruction
|
||||||
|
.define __sys_rawwrite
|
||||||
|
__sys_rawwrite:
|
||||||
|
movb ah, 0x40
|
||||||
|
mov bx, sp
|
||||||
|
mov dx, 4(bx)
|
||||||
|
mov cx, 6(bx)
|
||||||
|
mov bx, 2(bx)
|
||||||
|
int 0x21
|
||||||
|
jmp .sys_axret
|
42
plat/msdos86/libsys/sys_seteof.c
Normal file
42
plat/msdos86/libsys/sys_seteof.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set or reset the "end-of-file encountered" indicator for a particular fd.
|
||||||
|
* Assume that the fd is valid, and is being read from in text mode.
|
||||||
|
*/
|
||||||
|
int _sys_seteof(int fd, int eof)
|
||||||
|
{
|
||||||
|
int reqbegfd = fd & ~_FDVECMASK;
|
||||||
|
struct _fdmodes *p = &_sys_fdmodes;
|
||||||
|
_fdvec_t mask;
|
||||||
|
|
||||||
|
while (p->begfd != reqbegfd)
|
||||||
|
{
|
||||||
|
p = p->next;
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
if (!eof)
|
||||||
|
return 0;
|
||||||
|
if ((p = sbrk(sizeof(struct _fdmodes)))
|
||||||
|
== OUT_OF_MEMORY)
|
||||||
|
return -1;
|
||||||
|
p->next = _sys_fdmodes.next;
|
||||||
|
p->begfd = reqbegfd;
|
||||||
|
p->modevec = p->eofvec = 0;
|
||||||
|
_sys_fdmodes.next = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask = (_fdvec_t)1 << (fd & _FDVECMASK);
|
||||||
|
if (eof)
|
||||||
|
p->eofvec |= mask;
|
||||||
|
else
|
||||||
|
p->eofvec &= ~mask;
|
||||||
|
return 0;
|
||||||
|
}
|
55
plat/msdos86/libsys/sys_setmode.c
Normal file
55
plat/msdos86/libsys/sys_setmode.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set text/binary mode for a particular fd. Assume that the fd is valid,
|
||||||
|
* and that the mode is either O_TEXT or O_BINARY.
|
||||||
|
*
|
||||||
|
* Return the previous mode (either O_TEXT or O_BINARY) on success, -1 (with
|
||||||
|
* errno set) on error.
|
||||||
|
*/
|
||||||
|
int _sys_setmode(int fd, int mode)
|
||||||
|
{
|
||||||
|
int reqbegfd = fd & ~_FDVECMASK;
|
||||||
|
struct _fdmodes *p = &_sys_fdmodes;
|
||||||
|
_fdvec_t mask;
|
||||||
|
|
||||||
|
while (p->begfd != reqbegfd)
|
||||||
|
{
|
||||||
|
p = p->next;
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
if (mode == O_TEXT)
|
||||||
|
return O_TEXT;
|
||||||
|
if ((p = sbrk(sizeof(struct _fdmodes)))
|
||||||
|
== OUT_OF_MEMORY)
|
||||||
|
return -1;
|
||||||
|
p->next = _sys_fdmodes.next;
|
||||||
|
p->begfd = reqbegfd;
|
||||||
|
p->modevec = p->eofvec = 0;
|
||||||
|
_sys_fdmodes.next = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask = (_fdvec_t)1 << (fd & _FDVECMASK);
|
||||||
|
if (mode == O_BINARY)
|
||||||
|
{
|
||||||
|
if (p->modevec & mask)
|
||||||
|
return O_BINARY;
|
||||||
|
p->modevec |= mask;
|
||||||
|
p->eofvec &= ~mask;
|
||||||
|
return O_TEXT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(p->modevec & mask))
|
||||||
|
return O_TEXT;
|
||||||
|
p->modevec &= ~mask;
|
||||||
|
return O_BINARY;
|
||||||
|
}
|
||||||
|
}
|
61
plat/msdos86/libsys/write.c
Normal file
61
plat/msdos86/libsys/write.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* $Source$
|
||||||
|
* $State$
|
||||||
|
* $Revision$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "libsys.h"
|
||||||
|
|
||||||
|
ssize_t write(int fd, void* buffer, size_t count)
|
||||||
|
{
|
||||||
|
static const char crlf[2] = "\r\n";
|
||||||
|
int i;
|
||||||
|
char *p, *q;
|
||||||
|
size_t left, n;
|
||||||
|
ssize_t r, tot;
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (_sys_getmode(fd) == O_BINARY)
|
||||||
|
return _sys_rawwrite(fd, buffer, count);
|
||||||
|
|
||||||
|
/* If the file descriptor is an O_TEXT fd, translate LFs to CRLFs. */
|
||||||
|
p = buffer;
|
||||||
|
left = count;
|
||||||
|
tot = 0;
|
||||||
|
while (left)
|
||||||
|
{
|
||||||
|
q = memchr(p, '\n', left);
|
||||||
|
if (!q)
|
||||||
|
return _sys_rawwrite(fd, p, left);
|
||||||
|
|
||||||
|
n = q - p;
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
r = _sys_rawwrite(fd, p, n);
|
||||||
|
if (r <= 0)
|
||||||
|
return tot ? tot : r;
|
||||||
|
tot += r;
|
||||||
|
p += r;
|
||||||
|
left -= r;
|
||||||
|
if (r != n)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = _sys_rawwrite(fd, crlf, sizeof crlf);
|
||||||
|
if (r != 2)
|
||||||
|
{
|
||||||
|
if (r > 0)
|
||||||
|
r = 0;
|
||||||
|
return tot ? tot : r;
|
||||||
|
}
|
||||||
|
++tot;
|
||||||
|
++p;
|
||||||
|
--left;
|
||||||
|
}
|
||||||
|
return tot;
|
||||||
|
}
|
Loading…
Reference in a new issue