_main.c
/* Copyright (C) 1986 by Manx Software Systems, Inc. */

/*
 *	This is common startup code for both the CLI and the WorkBench.
 *	When called from the WorkBench, argc is 0 and argv points to a
 *	WBStartup type of structure.
 */

#include	<ctype.h>
#include	<exec/alerts.h>
#include	<libraries/dosexten.h>
#include	<workbench/startup.h>

void *SysBase, *DOSBase, *MathBase, *MathTransBase;
long _savsp;

int errno, Enable_Abort;

static int argc, arg_len;
static char **argv, *arg_lin;
static struct WBStartup *wb_msg;

long _Input(), _Output();

struct _dev {
	long	fd;
	short	mode;
} _devtab[20];

_main(alen, aptr)
long alen;
char *aptr;
{
	register unsigned short c;
	register char *cp;
	register struct Process *pp, *_FindTask();
	register struct CommandLineInterface *cli;
	register long l;
	struct FileHandle *fp;
	void *_AllocMem(), *_OpenLibrary();
	struct WBStartup *_GetMsg();
	long _Open();

	if ((DOSBase = _OpenLibrary(DOSNAME, LIBRARY_VERSION)) == 0) {
		Alert(AG_OpenLib|AO_DOSLib, 0L);
asmexit:
		;
#asm
		move.l	__savsp,sp		;get back original stack pointer
		rts						;and exit
#endasm
	}
	if ((MathBase = _OpenLibrary("mathffp.library", LIBRARY_VERSION)) == 0) {
		Alert(AG_OpenLib|AO_MathLib, 0L);
		goto asmexit;
	}

	pp = _FindTask(0L);
	if (pp->pr_CLI) {
		cli = (struct CommandLineInterface *) ((long)pp->pr_CLI << 2);
		cp = (char *)((long)cli->cli_CommandName << 2);
		arg_len = cp[0]+alen+2;
		arg_lin = _AllocMem((long)arg_len, 0L);
		strncpy(arg_lin, cp+1, cp[0]);
		strcpy(arg_lin+cp[0], " ");
		strncat(arg_lin, aptr, (int)alen+1);
		for (argc=0,cp=arg_lin;;argc++) {
			while (isspace(*cp))
				cp++;
			if (*cp < ' ')
				break;
			while ((c=*cp) && !isspace(c))
				cp++;
			*cp++ = 0;
			if (c == 0)
				break;
		}
		*cp = 0;
		argv = _AllocMem((long)(argc+1)*sizeof(*argv), 0L);
		for (c=0,cp=arg_lin;c<argc;c++) {
			while (isspace(*cp))
				cp++;
			argv[c] = cp;
			cp += strlen(cp) + 1;
		}
		argv[c] = 0;

		_devtab[0].fd = _Input();
		_devtab[0].mode = 0x8000;
		_devtab[1].fd = _Output();
		_devtab[1].mode = 0x8001;
		_devtab[2].fd = _Output();
		_devtab[2].mode = 0x8001;
		Enable_Abort = 1;
		main(argc, argv);
		_exit(0);
	}
	else {
		_WaitPort(&pp->pr_MsgPort);
		wb_msg = _GetMsg(&pp->pr_MsgPort);
		if (wb_msg->sm_ArgList)
			_CurrentDir(wb_msg->sm_ArgList->wa_Lock);
		if (wb_msg->sm_ToolWindow) {
			if (_devtab[0].fd = _Open(wb_msg->sm_ToolWindow, MODE_OLDFILE)) {
				_devtab[1].fd = _devtab[2].fd = _devtab[0].fd;
				_devtab[0].mode = 0x8000;
				_devtab[1].mode = _devtab[2].mode = 0x8001;
				fp = (struct FileHandle *) (_devtab[0].fd << 2);
				pp->pr_ConsoleTask = (APTR) fp->fh_Type;
			}
		}
		main(0, wb_msg);
		_exit(0);
	}
}

void (*_cln)() = 0;

_exit(code)
{
	int fd;

	for (fd = 0 ; fd < 10 ; fd++)
		close(fd);
	if (_cln)
		(*_cln)();
	if (MathTransBase)
		_CloseLibrary(MathTransBase);
	if (MathBase)
		_CloseLibrary(MathBase);
	if (wb_msg == 0) {
		_FreeMem(arg_lin, (long)arg_len);
		_FreeMem(argv, (long)(argc+1)*sizeof(*argv));
		_Exit((long)code);
	}
	else {
		_Forbid();
		_ReplyMsg(wb_msg);
#asm
		move.l	8(a5),d0		;pick up return exit code
		move.l	__savsp,sp		;get back original stack pointer
		rts						;and exit
#endasm
	}
}

abort.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

long
Chk_Abort()
{
	long x, _SetSignal(), _Write(), _Output();
	extern int Enable_Abort;

	if (((x = _SetSignal(0L, 0x1000L))&0x1000) == 0)
		return(0);
	if (Enable_Abort == 0)
		return(x);
	_Write(_Output(), "^C\n", 4L);
	exit(1);
}

access.c
/* Copyright (C) 1986 by Manx Software Systems, Inc. */

#include	<errno.h>
#include	<libraries/dos.h>

access(filename, mode)
char *filename;
int mode;
{
	long l, _Lock();
	int ret = -1;

	if ((l = _Lock(filename, ACCESS_READ)) == 0) {
		errno = ENOENT;
		return(-1);
	}
	switch(mode) {
	case 2:			/* write */
		_UnLock(l);
		if ((l = _Lock(filename, ACCESS_WRITE)) == 0) {
			errno = EACCES;
			return(-1);
		}
		/* FALL THRU */
	case 0:			/* existence */
	case 1:			/* execute (if file) or search (if directory) */
	case 4:			/* read */
		ret = 0;
		break;
	}
	_UnLock(l);
	return(ret);
}

close.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<errno.h>
#include	<fcntl.h>

extern struct _dev {
	long	fd;
	short	mode;
} _devtab[];

close(fd)
register int fd;
{
	register struct _dev *refp;
	register int i, err;

	refp = _devtab + fd;
	if (fd < 0 || fd > 19 || refp->fd == 0) {
		errno = EBADF;
		return(-1);
	}
	if ((refp->mode & 0x8000) == 0)
		_Close(refp->fd);
	refp->fd = 0;
	return(0);
}

crt0.a68
;:ts=8
; Copyright (C) 1986 by Manx Software Systems, Inc.
;


;	Initial startup routine for Aztec C. Assumes that first
;		instruction in program was JSR to .begin.

;	NOTE: code down to "start" must be placed at beginning of
;		all programs linked with Aztec Linker using small
;		code or small data.


	entry	.begin
	public	.begin
.begin
	move.l	(sp)+,a1		;get return address
	sub.w	#10,a1			;get segment list pointer
	move.l	(a1),d1			;get BPTR to data segment
	add.l	d1,d1			;convert to pointer
	add.l	d1,d1
	move.l	d1,a4			;move to A4
	add.l	#32770,a4		;bias appropriately
	lea	__Dend,a1
	lea	__Uorg,a2
	cmp.l	a1,a2			;check if BSS and DATA together
	bne	start			;no, don't have to clear
	move.w	#((__Uend-__Uorg)/4)-1,d1
	bmi	start			;skip if no bss
	move.l	#0,d2
loop
	move.l	d2,(a1)+		;clear out memory
	dbra	d1,loop

start
	move.l	sp,__savsp		;save stack pointer
	move.l	4,a6			;get Exec's library base pointer
	move.l	a6,_SysBase		;put where we can get it
	movem.l	d0/a0,-(sp)		;save CLI command parameters
	jsr	__main			;call the startup stuff
	add.w	#8,sp			;pop args
	rts				;and return

	public	__main

	dseg

	public	_SysBase,__savsp
	public	__Dend,__Uorg,__Uend

exec.a68
; Copyright (C) 1986 by Manx Software Systems, Inc.
;:ts=8

	near	code
	near	data

	public	_LVOUnLoadSeg
	public	_LVOLoadSeg
	public	_LVOExit

	public	__exec
__exec
	dc.l	0		;len of segment
	dc.l	0		;pointer to next segment
	move.l	stack,sp	;get a good stack location
	move.l	savret,-(sp)	;set up for real return
	move.l	seglist,d1	;get seglist of current program
	move.l	dosbase,a6	;get pointer to library
	jsr	_LVOUnLoadSeg(a6)	;unload the program

	move.l	cmdnam1,d1	;get pointer to cmd name
	jsr	_LVOLoadSeg(a6)	;load the new program
	tst.l	d0		;check on load
	bne	exec2		;skip if loaded okay
	move.l	cmdnam2,d1	;get pointer to df0: version
	jsr	_LVOLoadSeg(a6)	;load the new program
	tst.l	d0		;check on load
	bne	exec2		;skip if loaded okay
	jsr	fixlist		;add us to the seglist
	move.l	#1,d1		;else do Exit(1)
	jsr	_LVOExit(a6)	;no return from here

exec2
	jsr	fixlist
	move.l	cmdlen,d0	;set up for program call
	move.l	cmdstr,a0
	jmp	4(a1)		;and transfer to program

fixlist
	move.l	cliseg,a0	;pointer to CLI segment list
	move.l	d0,(a0)		;point CLI at new segment
	move.l	cliseg2,a1	;pointer to BCPL copy of segment list
	move.l	d0,(a1)		;point at new segment
	lsl.l	#2,d0		;convert BPTR to real address
	move.l	d0,a1		;save in a1 for jump
fix1
	move.l	(a0),d0		;get chain to next
	beq	fix2		;at end, break out of loop
	lsl.l	#2,d0		;convert BPTR to real address
	move.l	d0,a0		;copy to a0
	bra	fix1		;and loop
fix2
	lea	__exec+4,a2	;pointer to this segment
	move.l	a2,d0		;copy to d0
	lsr.l	#2,d0		;convert to BPTR
	move.l	d0,(a0)		;add us to list
	rts

dosbase	dc.l	0		;address of DOS library
seglist	dc.l	0		;BPTR to seglist of current program
stack	dc.l	0		;Ptr to return address
savret	dc.l	0		;place to save real return address
cliseg	dc.l	0		;pointer to cli seg list
cliseg2	dc.l	0		;pointer to bcpl seg list
cmdlen	dc.l	0		;length of command string
cmdstr	dc.l	0		;pointer to command string
cmdnam1	dc.l	0		;pointer to program name
cmdnam2	dc.l	0		;pointer to second name (df0:c/xxx)

	public	__endexec
__endexec

execv.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<exec/types.h>
#include	<exec/tasks.h>
#include	<libraries/dosexten.h>

execl(file, arg0)
char *file, *arg0;
{
	return(execv(file, &arg0));
}

struct ex {
	long	dosbase;
	BPTR	seglist;
	long *	stack;
	long	savret;
	BPTR *	cliseg;
	BPTR *	cliseg2;
	long	cmdlen;
	char *	cmdstr;
	char *	cmdnam1;
	char *	cmdnam2;
};

execv(arg, argv)
char *arg, **argv;
{
	register struct ex *ex;
	register struct CommandLineInterface *cli;
	struct Process *pp;
	struct Process *FindTask();
	register char **ap, *cp, *jp;
	int len;
	long *l, *k, *bcpl, *AllocMem();
	extern char _exec, _endexec;
	extern long DOSBase;
	extern long _savsp;

	for (len=0,ap=argv+1;*ap;ap++,len+=strlen(*ap)+1)
		;
	pp = FindTask(0L);
	cli = (struct CommandLineInterface *)((long)pp->pr_CLI <<  2);
	if (cli == 0) {
		return(-1);
	}
	bcpl = (long *)*((long *)*((long *)*((long *)*((long *)
												_savsp+2)+1)-3)-3)+107;
	if (*bcpl != cli->cli_Module) {
		return(-1);
	}
	len += &_endexec-&_exec + 1 + strlen(arg) + 1 + 8;
	len = (len + 3) & ~3;
	k = AllocMem((long)len, 0L);
	movmem(&_exec, k, len);
	*k = len;
	ex = (struct ex *)((char *)k + (long)(&_endexec-&_exec) -
													sizeof(struct ex));
	cp = (char *)(ex + 1);
	strcpy(cp, " ");
	for (ap=argv+1;*ap;ap++) {
		strcpy(cp, *ap);
		strcat(cp, " ");
		cp += strlen(cp);
	}
	strcat(cp, "\r");
	cp += strlen(cp);
	strcpy(++cp, arg);

	ex->dosbase = DOSBase;
	ex->seglist = cli->cli_Module;
	ex->stack = (long *)pp->pr_ReturnAddr;
	l = ex->stack - 1;
	ex->savret = *l;
	*l = (long)(k + 2);
	ex->cliseg = &cli->cli_Module;
	ex->cliseg2 = bcpl;
	ex->cmdlen = strlen(ex+1);
	ex->cmdstr = (char *)(ex + 1);
	ex->cmdnam1 = cp;
	ex->cmdnam2 = cp;
	jp = (char *)((long)cli->cli_CommandName<<2);
	*jp++ = strlen(cp);
	strcpy(jp, cp);
	exit(0);
}

execvp.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<exec/types.h>
#include	<exec/tasks.h>
#include	<libraries/dosexten.h>

execlp(file, arg0)
char *file, *arg0;
{
	return(execvp(file, &arg0));
}

struct ex {
	long	dosbase;
	BPTR	seglist;
	long *	stack;
	long	savret;
	BPTR *	cliseg;
	BPTR *	cliseg2;
	long	cmdlen;
	char *	cmdstr;
	char *	cmdnam1;
	char *	cmdnam2;
};

execvp(arg, argv)
char *arg, **argv;
{
	register struct ex *ex;
	register struct CommandLineInterface *cli;
	struct Process *pp;
	struct Process *FindTask();
	register char **ap, *cp, *jp;
	int len;
	long *l, *k, *bcpl, *AllocMem();
	extern char _exec, _endexec;
	extern long DOSBase;
	extern long _savsp;

	for (len=0,ap=argv+1;*ap;ap++,len+=strlen(*ap)+1)
		;
	pp = FindTask(0L);
	cli = (struct CommandLineInterface *)((long)pp->pr_CLI <<  2);
	if (cli == 0) {
		return(-1);
	}
	bcpl = (long *)*((long *)*((long *)*((long *)*((long *)
												_savsp+2)+1)-3)-3)+107;
	if (*bcpl != cli->cli_Module) {
		return(-1);
	}
	len += &_endexec-&_exec + 1 + strlen(arg) + 1 + 8 + 2;
	len = (len + 3) & ~3;
	k = AllocMem((long)len, 0L);
	movmem(&_exec, k, len);
	*k = len;
	ex = (struct ex *)((char *)k + (long)(&_endexec-&_exec) -
													sizeof(struct ex));
	cp = (char *)(ex + 1);
	strcpy(cp, " ");
	for (ap=argv+1;*ap;ap++) {
		strcpy(cp, *ap);
		strcat(cp, " ");
		cp += strlen(cp);
	}
	strcat(cp, "\r");
	cp += strlen(cp);
	strcpy(++cp, "c:");
	strcat(cp, arg);

	ex->dosbase = DOSBase;
	ex->seglist = cli->cli_Module;
	ex->stack = (long *)pp->pr_ReturnAddr;
	l = ex->stack - 1;
	ex->savret = *l;
	*l = (long)(k + 2);
	ex->cliseg = &cli->cli_Module;
	ex->cliseg2 = bcpl;
	ex->cmdlen = strlen(ex+1);
	ex->cmdstr = (char *)(ex + 1);
	ex->cmdnam1 = cp+2;
	ex->cmdnam2 = cp;
	jp = (char *)((long)cli->cli_CommandName<<2);
	*jp++ = strlen(cp+2);
	strcpy(jp, cp+2);
	exit(0);
}

exit.c
/* Copyright (C) 1986 by Manx Software Systems, Inc. */

int (*cls_)() = 0;

exit(code)
{
	if (cls_)
		(*cls_)();
	_exit(code);
}

fexec.c
/* Copyright (C) 1986 by Manx Software Systems, Inc. */

#include	<exec/types.h>
#include	<exec/tasks.h>
#include	<libraries/dosexten.h>

static long ret_val;

wait()
{
	return(ret_val);
}

fexecl(file, arg0)
char *file, *arg0;
{
	return(execvp(file, &arg0));
}

fexecv(cmd, argv)
char *cmd, **argv;
{
	register struct CommandLineInterface *cli;
	struct Process *pp;
	struct Process *FindTask();
	register char **ap, *cp, *arg;
	APTR sav_ret;
	long len, seg, sav_seg;
	long *l, *bcpl, *stk;
	struct FileHandle *fhp;
	long doexec(), LoadSeg();
	void *AllocMem();
	char buf[40];

	pp = FindTask(0L);
	if ((cli = (struct CommandLineInterface *)((long)pp->pr_CLI << 2)) == 0) {
		return(-1);
	}
	bcpl = (long *)*((long *)*((long *)*((long *)*((long *)
										pp->pr_ReturnAddr+1)+1)-3)-3)+107;
	if (*bcpl != cli->cli_Module) {
		return(-1);
	}
	if ((seg = LoadSeg(cmd)) == 0) {
		strcpy(buf, "c:");
		strcat(buf, cmd);
		if ((seg = LoadSeg(buf)) == 0) {
			return(-1);
		}
	}
	sav_seg = cli->cli_Module;
	cli->cli_Module = seg;
	*bcpl = seg;

	stk = (long *) AllocMem(4*cli->cli_DefaultStack+8, 0L);
	*stk = 4*cli->cli_DefaultStack + 8;
	stk = (long *)((long)stk + 4*cli->cli_DefaultStack);
	stk[0] = 4*cli->cli_DefaultStack;
	stk[1] = ((long *)pp->pr_ReturnAddr)[1];
	sav_ret = pp->pr_ReturnAddr;
	pp->pr_ReturnAddr = (APTR) stk;

	for (len=1,ap=argv+1;*ap;ap++)
		len += strlen(*ap) + 1;
	cp = arg = AllocMem(len, 0L);
	for (ap=argv+1;*ap;ap++) {
		strcpy(cp, *ap);
		strcat(cp, " ");
		cp += strlen(cp);
	}
	arg[len-1] = '\n';

	cp = (char *)((long)cli->cli_CommandName << 2);
	movmem(cp, buf, 40);
	strcpy(cp+1, cmd);
	cp[0] = strlen(cmd);

	fhp = (struct FileHandle *) (pp->pr_CIS << 2);
	strncpy(fhp->fh_Buf<<2, arg, (int)(len < 200?len:199));
	fhp->fh_Pos = 0;
	fhp->fh_End = len < 200?len:199;

	ret_val = doexec(len, arg, (seg+1)<<2, stk);

	fhp->fh_Pos = fhp->fh_End;
	UnLoadSeg(cli->cli_Module);
	pp->pr_ReturnAddr = sav_ret;
	cli->cli_Module = sav_seg;
	*bcpl = sav_seg;
	FreeMem(arg, len);
	movmem(buf, cp, 40);
	return(0);
}

static
long
doexec()
{
#asm
	movem.l	d4-d7/a2-a5,-(sp)		;save registers
	lea		savsp,a0
	move.l	sp,(a0)					;save our sp
	movem.l	8(a5),d0/a0/a4/a7		;load params
	move.l	4(sp),a3				;get old sp from CLI
	movem.l	4(a3),a1/a2/a5/a6		;get BCPL environment
	move.l	d0,12(a1)				;set length
	move.l	a0,d1					;copy to dreg
	lsr.l	#2,d1					;convert to BPTR
	move.l	d1,8(a1)				;set ptr
	jsr		(a4)					;call new program
	movem.l	(sp)+,d2/d3				;get stk siz and old sp
	move.l	sp,a1					;save current sp
	move.l	savsp,sp				;get back our sp
	movem.l	(sp)+,d4-d7/a2-a5		;get back registers
	move.l	d0,-(sp)				;save return code
	sub.l	d2,a1					;back up a bit
	sub.l	#8,a1					;back up over header
	move.l	(a1),d0					;get size to free
	move.l	4,a6					;get ExecBase
	jsr		_LVOFreeMem#(a6)		;free the memory
	move.l	(sp)+,d0				;get the return code
#endasm
}

#asm
savsp:
	dc.l	0
#endasm
getenv.c
struct lib {
	struct lib *succ, *prev;
	char type, priority;
	char *name;
	short flags;
	short negsize;
	short possize;
	short version;
	short revision;
	char *ID;
	long sum;
	short opencnt;
	char *env;
};

char *
getenv(str)
char *str;
{
	register struct lib *lp, *_OpenLibrary();
	register char *cp, *np, *malloc(), *index();
	register int i;

	if ((lp = _OpenLibrary("environment", 0L)) == 0)
		return(0);
	_CloseLibrary(lp);
	cp = lp->env;
	i = strlen(str);
	while (*cp) {
		if ((np = index(cp, '=')) && np-cp == i && strncmp(cp, str, i) == 0) {
			cp = malloc(strlen(++np)+1);
			strcpy(cp, np);
			return(cp);
		}
		cp += strlen(cp) + 1;
	}
	return(0);
}

isatty.c
/* Copyright (C) 1986 by Manx Software Systems, Inc. */

extern struct _dev {
	long	fd;
	short	mode;
} _devtab[];

isatty(fd)
{
	long _IsInteractive();

	return(_IsInteractive(_devtab[fd].fd) != 0);
}

lseek.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<errno.h>
#include	<fcntl.h>

extern struct _dev {
	long	fd;
	short	mode;
} _devtab[];

long _IoErr(), _Seek();

long
lseek(fd, pos, mode)
register int fd;
long pos;
{
	register struct _dev *refp;
	register long err;

	Chk_Abort();
	refp = _devtab + fd;
	if (fd < 0 || fd > 19 || refp->fd == 0) {
		errno = EBADF;
		return(-1);
	}
	if ((err = _Seek(refp->fd, pos, (long)mode-1)) == -1) {
		errno = _IoErr();
		return(-1);
	}
	return(_Seek(refp->fd, 0L, 0L));
}

makefile

.c.r:
	c68 +b $(CFLAGS) -o $@ $*.c

.c.r32:
	c68 +bl $(CFLAGS) -o $@ $*.c

.a68.r:
	as68 $*.a68

ALL=_main.r abort.r access.r crt0.r exec.r\
	execv.r execvp.r fexec.r open.r close.r\
	read.r write.r lseek.r exit.r getenv.r\
	isatty.r rename.r stat.r unlink.r
ALL32=_main.r32 abort.r32 access.r32 crt0.r exec.r\
	execv.r32 execvp.r32 fexec.r32 open.r32 close.r32\
	read.r32 write.r32 lseek.r32 exit.r32 getenv.r32\
	isatty.r32 rename.r32 stat.r32 unlink.r32

all:	$(ALL) $(ALL32)

open.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<errno.h>
#include	<fcntl.h>
#include	<libraries/dos.h>

extern struct _dev {
	long	fd;
	short	mode;
} _devtab[];

creat(name, mode)
char *name;
{
	return(open(name, O_WRONLY|O_TRUNC|O_CREAT, mode));
}

open(name, flag, mode)
register char *name;
{
	register struct _dev *refp;
	register long file;
	register int fd, err;
	long _Open(), _IoErr(), _DeleteFile(), _Lock();

	Chk_Abort();
	refp = _devtab;
	for (fd=0;fd<20;fd++)
		if (refp[fd].fd == 0)
			goto found;
	err = EMFILE;
	goto xerr;
found:
	if (flag & O_TRUNC) {
		if (file = _Lock(name, ACCESS_WRITE)) {
			_UnLock(file);
			if (_DeleteFile(name) == 0 && (err=_IoErr()) != 205)
				goto xerr;
		}
	}
	file = _Open(name, MODE_OLDFILE);
	if (file == 0) {
		if ((flag&O_CREAT) == 0) {
			err = ENOENT;
			goto xerr;
		}
		if ((file = _Open(name, MODE_NEWFILE)) == 0) {
			err = _IoErr();
			goto xerr;
		}
	/*
	 *	this kludge is necessary till the RAM: driver gets fixed
	 */
		_Write(file, "", 1L);
		_Seek(file, 0L, -1L);
	}
	else if ((flag&(O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) {
		_Close(file);
		err = EEXIST;
xerr:
		errno = err;
		return(-1);
	}
	refp[fd].fd = file;
	refp[fd].mode = flag;
	if (flag & O_APPEND)
		_Seek(file, 0L, OFFSET_END);
	return(fd);
}

read.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<errno.h>
#include	<fcntl.h>

extern struct _dev {
	long	fd;
	short	mode;
} _devtab[];

long _IoErr(), _Read();

read(fd, buf, len)
char *buf;
register int fd;
unsigned int len;
{
	register struct _dev *refp;
	register long err;

	Chk_Abort();
	refp = _devtab + fd;
	if (fd < 0 || fd > 19 || refp->fd == 0) {
		errno = EBADF;
		return(-1);
	}
	if ((refp->mode & 3) == O_WRONLY) {
		errno = EINVAL;
		return(-1);
	}
	if ((err = _Read(refp->fd, buf, (long)len)) == -1) {
		errno = _IoErr();
		return(-1);
	}
	return((int)err);
}

rename.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<errno.h>
#include	<libraries/dos.h>

long _Rename(), _IoErr(), _Lock(), _UnLock();

rename(old, new)
char *old, *new;
{
	long l;

	if (l = _Lock(new, ACCESS_READ)) {
		_UnLock(l);
		errno = EEXIST;
		return(-1);
	}
	if (_Rename(old, new) == 0) {
		errno = _IoErr();
		return(-1);
	}
	return(0);
}

stat.c
#include	<stat.h>
#include	<exec/exec.h>
#include	<libraries/dosextens.h>

stat(name, buf)
char *name;
struct stat *buf;
{
	long l, _Lock();
	struct FileInfoBlock *fp, *AllocMem();

	if ((l=_Lock(name, ACCESS_READ)) == 0) {
		return(-1);
	}
	fp = AllocMem((long)sizeof *fp, 0L);
	_Examine(l, fp);
	buf->st_attr = fp->fib_Protection;
	buf->st_mtime = fp->fib_Date.ds_Days * 24 * 60 * 60 +
					fp->fib_Date.ds_Minute * 60 +
					fp->fib_Date.ds_Tick/TICKS_PER_SECOND;
	buf->st_size = fp->fib_Size;
	_FreeMem(fp, (long) sizeof *fp);
	_UnLock(l);
	return(0);
}

unlink.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<errno.h>

long _DeleteFile(), _IoErr();

unlink(name)
char *name;
{
	if (_DeleteFile(name) == 0) {
		errno = _IoErr();
		return(-1);
	}
	return(0);
}
write.c
/* Copyright (C) 1985 by Manx Software Systems, Inc. */

#include	<errno.h>
#include	<fcntl.h>

extern struct _dev {
	long	fd;
	short	mode;
} _devtab[];

long _IoErr(), _Write();

write(fd, buf, len)
char *buf;
register int fd;
unsigned int len;
{
	register struct _dev *refp;
	register long err;

	Chk_Abort();
	refp = _devtab + fd;
	if (fd < 0 || fd > 19 || refp->fd == 0) {
		errno = EBADF;
		return(-1);
	}
	if ((refp->mode & 3) == O_RDONLY) {
		errno = EINVAL;
		return(-1);
	}
	if ((err = _Write(refp->fd, buf, (long)len)) == -1) {
		errno = _IoErr();
		return(-1);
	}
	return((int)err);
}

