koreth%panarthea.ebay@sun.com (Steven Grimm) (08/20/89)
Submitted-by: uunet.UU.NET!unido!sbsvax!roeder (Edgar Roeder)
Posting-number: Volume 2, Issue 75
Archive-name: gcclib2/part04
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 4 (of 7)."
# Contents: memory.c.cdiff pexecv.c signal.c stat.c system.c timer.c
# Wrapped by roeder@sbsvax on Wed Aug 16 22:03:02 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'memory.c.cdiff' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'memory.c.cdiff'\"
else
echo shar: Extracting \"'memory.c.cdiff'\" \(4440 characters\)
sed "s/^X//" >'memory.c.cdiff' <<'END_OF_FILE'
X*** terminator/memory.c Fri Aug 11 18:52:40 1989
X--- new-lib/memory.c Thu Aug 3 22:37:44 1989
X***************
X*** 1 ****
X--- 1,14 ----
X+ /* Added malloc_init and warnfunction for emacs support
X+ * This will only work if you set _stksize = -1. Otherwise we have no
X+ * correct lim_data and data_bytes_unused
X+ * [[ i have a solution for this, but i included this stuff for emacs only ]]
X+ * er (Edgar Roeder)
X+ */
X+ /* Changed 89/02/06, AD (Atze Dijkstra )
X+ System request made dependant of _heapbase, init in crt0.s.
X+ If != NULL, mem will not be requested via Malloc,
X+ but heap and stack are contiguous and consume almost
X+ all the free mem.
X+ Corrected 23-Jun-1989 by Piet van Oostrum
X+ */
X
X***************
X*** 3,4 ****
X--- 16,25 ----
X
X+ extern char * _heapbase ; /*AD, PvO*/
X+ extern char * _stksize ; /*AD, PvO*/
X+
X+ static long malloc_bytes_in_free_list = 0;
X+
X+ long malloc_sbrk_used = 0;
X+ long malloc_sbrk_unused = 1024000; /* only dummy initializer */
X+
X /* minimum chunk to ask OS for */
X***************
X*** 6,9 ****
X
X- #include <osbind.h>
X-
X #define NULL 0
X--- 27,28 ----
X***************
X*** 20,21 ****
X--- 39,91 ----
X
X+ /* Number of bytes of writable memory we can expect to be able to get */
X+ static long lim_data = 0;
X+
X+ /* Level number of warnings already issued.
X+ 0 -- no warnings issued.
X+ 1 -- 75% warning already issued.
X+ 2 -- 85% warning already issued.
X+ */
X+ static int warnlevel;
X+
X+ /* Function to call to issue a warning;
X+ 0 means don't issue them. */
X+ static void (*warnfunction) ();
X+
X+ /* Cause reinitialization based on job parameters;
X+ also declare where the end of pure storage is. */
X+ void
X+ malloc_init (start, warnfun) /* ignore start - it's for emacs to get happy */
X+ char *start;
X+ void (*warnfun) ();
X+ {
X+ malloc_sbrk_unused = lim_data = 0;
X+ warnlevel = 0;
X+ if (warnfun != (void (*)) -1)
X+ warnfunction = warnfun;
X+ }
X+
X+ static char * HeapAlloc( sz ) /*AD, PvO*/
X+ unsigned long sz ; /*AD*/
X+ { /*AD*/
X+
X+ char slush [64]; /*PvO*/
X+ register char* sp ; /*AD, PvO*/
X+ int available;
X+ /*AD*/
X+ sp = slush; /*AD, PvO*/
X+ available = (int) (sp - _heapbase + sz);
X+ if (!lim_data) lim_data = available;
X+ if ( available < 0 ) /*AD, PvO, er*/
X+ { /*AD*/
X+ return( NULL ) ; /*AD*/
X+ } /*AD*/
X+ malloc_sbrk_unused = available + malloc_bytes_in_free_list;
X+ malloc_bytes_in_free_list += sz;
X+ sp = _heapbase ; /*AD*/
X+ _heapbase += sz ; /*AD*/
X+ _stksize -= sz ; /*AD*/
X+ /*AD*/
X+ return( sp ) ; /*AD*/
X+ } /*AD*/
X+
X char * malloc(n)
X***************
X*** 62,65 ****
X */
X! /* q = (struct mem_chunk * )trap_1_wlww(0x48, sz); */
X! q = (struct mem_chunk * )Malloc(sz);
X /*
X--- 132,137 ----
X */
X! if ( _heapbase ) /*AD*/
X! q = (struct mem_chunk * )HeapAlloc( sz ) ; /*AD*/
X! else /*AD*/
X! q = (struct mem_chunk * )trap_1_wlww(0x48, sz);
X /*
X***************
X*** 68,69 ****
X--- 140,162 ----
X */
X+ if(warnfunction)
X+ switch (warnlevel) {
X+ case 0:
X+ if (malloc_sbrk_used > (lim_data / 4) * 3) {
X+ warnlevel++;
X+ (*warnfunction) ("Warning: past 75% of memory limit\n");
X+ }
X+ break;
X+ case 1:
X+ if (malloc_sbrk_used > (lim_data / 20) * 17) {
X+ warnlevel++;
X+ (*warnfunction) ("Warning: past 85% of memory limit\n");
X+ }
X+ break;
X+ case 2:
X+ if (malloc_sbrk_used > (lim_data / 20) * 19) {
X+ warnlevel++;
X+ (*warnfunction) ("Warning: past 95% of memory limit\n");
X+ }
X+ break;
X+ }
X if (((long)q) <= 0) /* can't alloc any more? */
X***************
X*** 94,95 ****
X--- 187,191 ----
X */
X+ malloc_sbrk_used += q->size;
X+ malloc_sbrk_unused -= q->size;
X+ malloc_bytes_in_free_list -= q->size;
X return((char * )++q);
X***************
X*** 102,103 ****
X--- 198,200 ----
X
X+ if (!r) return;
X /* move back to uncover the mem_chunk */
X***************
X*** 104,105 ****
X--- 201,205 ----
X r--; /* there it is! */
X+ malloc_sbrk_used -= r->size;
X+ malloc_sbrk_unused += r->size;
X+ malloc_bytes_in_free_list += r->size;
X /*
X***************
X*** 158,160 ****
X { /* block too small, get new one */
X! dst = q = (struct mem_chunk * )malloc(n);
X if (q != NULL)
X--- 258,260 ----
X { /* block too small, get new one */
X! dst = (long *) q = (struct mem_chunk * )malloc(n);
X if (q != NULL)
X***************
X*** 190,191 ****
X }
X-
X--- 290 ----
END_OF_FILE
if test 4440 -ne `wc -c <'memory.c.cdiff'`; then
echo shar: \"'memory.c.cdiff'\" unpacked with wrong size!
fi
# end of 'memory.c.cdiff'
fi
if test -f 'pexecv.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'pexecv.c'\"
else
echo shar: Extracting \"'pexecv.c'\" \(3861 characters\)
sed "s/^X//" >'pexecv.c' <<'END_OF_FILE'
X#ifdef test
X#define testmain
X#include <stdio.h>
X#endif
X#include <osbind.h>
X#include <ctype.h>
X#include <time.h>
X
X#define alloca __builtin_alloca
X
Xclock_t _child_runtime;
Xchar *xarg_pattern = "xArg=00000000";
Xchar *pbp_pattern = "PBP=%ld";
X
Xint
XPexecv(int mode, const char *command, char *argv[], char *env[])
X{
X extern char **environ;
X register char *new_env;
X register int env_len = 0;
X register int arg_len = 30; /* "PBP=%ld\0ARGV=" + 10 bytes slack */
X register char *cp;
X register char **ap, **ep;
X register int i;
X int old_parameter_passing;
X char *tail;
X char cmd[strlen(command)+1];
X int old_input, old_output, in, out;
X clock_t start_time;
X short argc;
X struct {
X long magic;
X short argc;
X char **argv;
X char *iovector;
X long parent;
X } xarg_vector;
X extern long _base;
X
X strcpy(cmd, command);
X unix_to_tos(cmd);
X if(!env) env = environ;
X#ifdef test
X printf("Pexecv(%d,%s,%06lx,%06lx)\n",mode,cmd,argv,env);
X printf("calculating environment length ..."); fflush(stdout);
X#endif
X ep = env;
X if(ep) while(*ep) env_len += 1 + strlen(*ep++);
X#ifdef test
X printf(" done (%d)\n", env_len);
X printf("calculating argument length ..."); fflush(stdout);
X#endif
X ap = argv;
X argc = 0;
X if(ap) while(*ap) {
X arg_len += 1 + strlen(*ap++);
X argc++;
X }
X#ifdef test
X printf(" done (%d, %d args)\n", arg_len, argc);
X printf("copying environment ...\n");
X#endif
X cp = new_env = alloca(env_len+arg_len+1);
X ep = env;
X if(ep) while(*ep && strncmp("ARGV=",*ep,5)) {
X /* don't pass our own arguments */
X#ifdef test
X printf("copy '%s'", *ep);
X#endif
X if(strncmp(xarg_pattern,*ep,5) && strncmp(pbp_pattern,*ep,4)) {
X strcpy(cp,*ep++);
X cp += strlen(cp) + 1;
X#ifdef test
X printf("\n");
X#endif
X } else {
X ep++;
X#ifdef test
X printf(" skipped\n");
X#endif
X }
X }
X#ifdef test
X printf("copying environment ... done\n");
X#endif
X in = out = old_input = old_output = -10;
X if(old_parameter_passing = isupper(argv[0][0])) {
X /* This is for old compiler passes not recognizing xArg */
X strcpy(cp,"ARGV=CCC?");
X cp += 10;
X }
X tail = alloca(arg_len);
X *tail = '\0';
X ap = argv;
X if(ap) while(1) {
X strcpy(cp,*ap++);
X if((*cp == '<' || *cp == '>') && !cp[1] && *ap) {
X if(*cp == '>') {
X old_output = Fdup(1);
X Fforce(1, out = creat(*ap++, 0664));
X } else {
X old_input = Fdup(0);
X Fforce(0, in = open(*ap++, 0));
X }
X } else if(old_parameter_passing) cp += strlen(cp) + 1;
X if(!*ap) break;
X strcat(tail," ");
X strcat(tail,*ap);
X }
X *cp = '\0';
X i = strlen(tail);
X if(i > 126) i = 126;
X *tail = i - 1;
X tail[i] = '\0';
X strcat(tail+1,"\r");
X if(!old_parameter_passing) {
X long tmp;
X#ifdef test
X char *savepos;
X#endif
X
X xarg_vector.magic = 0x78417267;
X xarg_vector.iovector = (char *) 0;
X xarg_vector.parent = _base;
X xarg_vector.argv = argv;
X xarg_vector.argc = argc;
X strcpy(cp,xarg_pattern);
X#ifdef test
X savepos = cp;
X#endif
X cp += 13;
X tmp = (long) &xarg_vector;
X while(tmp) {
X *--cp = "0123456789ABCDEF"[tmp & 0x0F];
X tmp >>= 4;
X }
X#ifdef test
X printf("xArg Parameters\n");
X printf("Environment variable = '%s'\n",savepos);
X printf("\t magic = '%4s'\n",&(xarg_vector.magic));
X printf("\tiovector = %08lx\n",xarg_vector.iovector);
X printf("\t parent = %08lx\n",xarg_vector.parent);
X printf("\t argc = %d\n",xarg_vector.argc);
X printf("\t argv = %08lx\n",xarg_vector.argv);
X#endif
X }
X start_time = clock();
X i = (Pexec(mode, cmd, tail, new_env));
X _child_runtime += clock() - start_time;
X#ifdef test
X printf("Pexec() returns %X = %d\n", i, i);
X#endif
X if(old_output != -10) Fforce(1, old_output);
X Fclose(old_output);
X close(out);
X if(old_input != -10) Fforce(0, old_input);
X Fclose(old_input);
X close(in);
X#ifdef test
X fprintf(stderr, "Pexec() returns %X = %d\n", i, i);
X#endif
X return(i);
X}
X
X#ifdef testmain
Xmain(int argc, char *argv[])
X{
X printf("argc = %d\n", argc);
X Pexecv(0, "a.out", argv, 0L);
X}
X#endif
END_OF_FILE
if test 3861 -ne `wc -c <'pexecv.c'`; then
echo shar: \"'pexecv.c'\" unpacked with wrong size!
fi
# end of 'pexecv.c'
fi
if test -f 'signal.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'signal.c'\"
else
echo shar: Extracting \"'signal.c'\" \(5591 characters\)
sed "s/^X//" >'signal.c' <<'END_OF_FILE'
X/*
X * Cross Development System for Atari ST
X * Copyright (c) 1988, Memorial University of Newfoundland
X *
X * Use a signal stack when serving signals arrived in super mode (er) 14.8.89
X *
X * Added execute_in_user_mode and changed sig_array type, added some new
X * signals (SIGUSR, SIGHUP) (er)
X *
X * Adapted to ANSI-C (_do_signal renamed to raise) (er)
X * added return value and error checking to raise (er)
X *
X * Signal routine - the signals are actually done by calling the _do_signal
X * routine - similiar to kill() I guess.
X *
X * $Header: signal.c,v 1.1 88/02/03 22:58:53 m68k Exp $
X *
X * $Log: signal.c,v $
X * Revision 1.1 88/02/03 22:58:53 m68k
X * Initial revision
X *
X */
X#include <signal.h>
X#include <errno.h>
X#include <osbind.h>
X#include <stdlib.h>
X
Xstatic void stop(int);
Xextern void _exit(int);
X
X/* ANSI C says that signal handlers have type (void (*)(int)) but even gcc */
X/* assumes that it's (int (*)(int)) */
X
X#define my_exit ((sig_handler_t *) exit)
X#define my_quit ((sig_handler_t *) _exit)
X#define my_stop ((sig_handler_t *) stop)
X
Xstatic struct sigarray_str {
X sig_handler_t *s_func; /* actual handler */
X sig_handler_t *d_func; /* default handler */
X} sig_array[NSIG] = {
X { SIG_DFL, SIG_IGN }, /* SIGNULL */
X { SIG_DFL, SIG_IGN }, /* SIGALRM */
X { SIG_DFL, my_exit }, /* SIGSEGV */
X { SIG_DFL, my_exit }, /* SIGODD */
X { SIG_DFL, my_exit }, /* SIGILL */
X { SIG_DFL, SIG_IGN }, /* SIGZDIV */
X { SIG_DFL, my_exit }, /* SIGCHK */
X { SIG_DFL, my_exit }, /* SIGTRAP */
X { SIG_DFL, my_exit }, /* SIGPRIV */
X { SIG_DFL, SIG_IGN }, /* SIGTRACE */
X { SIG_DFL, my_exit }, /* SIGINT */
X { SIG_DFL, my_exit }, /* SIGQUIT */
X { SIG_DFL, my_stop }, /* SIGTSTP */
X { SIG_DFL, SIG_IGN }, /* SIGFPE */
X { SIG_IGN, my_exit }, /* SIGHUP */
X { SIG_DFL, my_quit }, /* SIGABRT */
X { SIG_DFL, my_exit }, /* SIGTERM */
X { SIG_DFL, SIG_IGN }, /* SIGUSR1 */
X { SIG_DFL, SIG_IGN }, /* SIGUSR2 */
X};
X
X#undef my_exit
X#undef my_quit
X#undef my_stop
X
Xsig_handler_t *
Xsignal(int sig, sig_handler_t *func)
X{
X sig_handler_t *oldfunc;
X
X if (sig >= 0 && sig < NSIG) {
X oldfunc = sig_array[sig].s_func;
X sig_array[sig].s_func = func;
X } else {
X errno = EINVAL;
X oldfunc = SIG_ERR;
X }
X return oldfunc;
X}
X
Xvolatile char _sig_done; /* needed for pause.c */
Xstatic long _signal_stack[256];
Xstatic long *const signal_stack = _signal_stack+256;
X
X/* We can't just switch the stack pointers to execute in usermode since */
X/* there are some programs which use their userstack as supervisorstack */
X/* too. We use a special signal stack which is reset to it's start if a */
X/* signal is received in supervisor mode. This is safe because the only */
X/* way to get back to the supervisor mode if you are in user mode would */
X/* use a call to the operating system (and so to the standard library), */
X/* which leeds to undefined behavior according to ANSI C. If we get the */
X/* signal in usermode we need not to worry about the stack. */
Xstatic /* no inline */ void
Xexecute_in_usermode(sig_handler_t *func, int param)
X{
X auto int super_mode; /* Avoid any problems with func by */
X auto long super_stack; /* putting these important vars on */
X auto long user_stack; /* the stack and not in registers. */
X
X if (super_mode = Super(1)) {
X asm ("movel sp, %0" : "=g" (super_stack));
X asm ("movel usp, %0" : "=a" (user_stack));
X asm ("andiw #0xDFFF, sr"); /* switch to the user mode */
X asm ("movel %0, sp" :: "g" (signal_stack));
X }
X (void) (*func)(param); /* this is executed in user mode */
X /* In the following cases we would never return to here: */
X /* - func terminates with exit or abort */
X /* - func terminates with a longjmp */
X /* In both of the cases we don't need to know where the */
X /* userstack pointer was before the supervisormode was */
X /* entered since we don't want to get back there either. */
X if (super_mode) {
X Super(super_stack - 6); /* this uses the user stack! */
X /* Don't worry about deferred popping of param above when we */
X /* have optimized this code with gcc -O. Just set the usp to */
X /* the old value recorded at the start of this function. Any */
X /* wrong setting of the ssp due to incorrect implementations */
X /* of Super will be corrected by the following "unlk a6". */
X asm ("movel %0, usp" :: "a" (user_stack));
X }
X}
X
Xstatic void
Xstop(int sig)
X{
X Fwrite(2,23,"\r\nProgram stopped !!!\r\n");
X system("-i"); /* interactively call the shell at *_shell_p */
X Fwrite(1,2,"\33e"); /* some shells switch the cursor off on exit */
X}
X
Xint
Xraise(int sig)
X{
X sig_handler_t *func;
X
X if (sig >= 0 && sig < NSIG) {
X /* we have to make sure that we call the signal-handler */
X /* in user mode, to avoid problems on super stack later */
X func = sig_array[sig].s_func;
X if (func == SIG_DFL) func = sig_array[sig].d_func;
X if (func != SIG_IGN) {
X /* ANSI C requires either signal(sig,SIG_DFL) or an */
X /* "implementation defined blocking of the signal". */
X /* This blocking can be done by setting a flag which */
X /* is cleared here after the call or in longjmp. But */
X /* what about this scenario: signal(sig,abort) and */
X /* signal(SIGABRT,func) and func doing a longjmp ? */
X if(sig != SIGILL) sig_array[sig].s_func = SIG_DFL;
X execute_in_usermode(func,sig);
X _sig_done = 1;
X }
X /* else ignore it */
X return(0);
X }
X /* invalid request for non existant signal */
X errno = EINVAL;
X return(-1);
X}
X
Xvoid
Xkill(int sig, int pid)
X{
X extern const long _base;
X
X if(pid == _base) raise(sig); /* we can't process kill requests */
X /* for other programs cause we do */
X /* not know their signal-handlers */
X}
END_OF_FILE
if test 5591 -ne `wc -c <'signal.c'`; then
echo shar: \"'signal.c'\" unpacked with wrong size!
fi
# end of 'signal.c'
fi
if test -f 'stat.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'stat.c'\"
else
echo shar: Extracting \"'stat.c'\" \(4534 characters\)
sed "s/^X//" >'stat.c' <<'END_OF_FILE'
X/*
X * Cross Development System for Atari ST
X * Copyright (c) 1988, Memorial University of Newfoundland
X *
X * er: coupled this code with opendir/readdir/closedir, added fstat
X *
X * er: added inode stuff, file attributes (including executable), /dev/null
X *
X * The only thing that doesn't get filled in at all is st_ino - it really
X * should be a unique number for each file - any ideas?
X *
X * $Header: stat.c,v 1.2 88/01/29 17:31:52 m68k Exp $
X *
X * $Log: stat.c,v $
X *
X * added fstat, inode numbers, more info about file modes and conversion of
X * unix names to tos syntax (er)
X *
X * 1.2 jrd
X *
X * Revision 1.1 88/01/29 17:31:52 m68k
X * Initial revision
X *
X */
X#include <types.h>
X#include <stat.h>
X#include <ctype.h>
X#include <errno.h>
X#include <osbind.h>
X#include <string.h>
X#include <param.h>
X#include <file.h>
X#include <dir.h>
X
Xstatic ino_t inode = 2; /* FIX_ME: inodes are different in readdir */
XDIR *_current_open_directory = (DIR *) 0;
X
Xint
Xfstat(int fd, struct stat *st)
X{
X if((fd >= 0) && (fd < N_HANDLES) && __handle_to_name[fd]) {
X return(stat(__handle_to_name[fd], st));
X } else {
X errno = EBADF;
X return -1;
X }
X}
X
Xint
Xstat(p, st)
X char *p;
X struct stat *st;
X{
X char path[strlen(p)+1];
X int rval;
X struct _dta dtabuf;
X extern long _time();
X int fd;
X short magic;
X short dots;
X int len;
X
X strcpy(path,p);
X if(!strcmp(p,"/dev/null")) {
X st->st_mode = S_IFBLK | 0666;
X st->st_attr = FA_LABEL;
X st->st_ino = 1;
X goto specials;
X }
X unix_to_tos(path);
X len = strlen(path);
X if (path[len-1] == '\\' || len == 2 && path[1] == ':') {
X if (len > 3 || len > 1 && path[1] != ':') {
X path[--len] = 0;
X } else { /* root directory */
Xroot_dir:
X st->st_mode = S_IFDIR | 0755;
X st->st_attr = FA_DIR;
X st->st_ino = 2; /* In root dir '.' and '..' have the */
X /* same inode number; we should also */
X /* differentiate between the drives. */
Xspecials:
X st->st_mtime = st->st_ctime = st->st_atime = 0;
X goto fill_in;
X }
X }
X if (!path) {
X errno = EFAULT;
X return -1;
X }
X if (index(path, '*') || index(path, '?')) {
X errno = EPATH;
X return -1;
X }
X if ((rval = Fsetdta(&dtabuf)) < 0) {
X errno = -rval;
X return -1;
X }
X dots = 0;
X if (*path == '.') {
X dots++;
X if (len > 1) {
X if (len == 2 && path[1] == '.') dots++;
X else dots = 0;
X }
X }
X if (dots) {
X char actual_path[MAXPATHLEN];
X
X Dgetpath(actual_path,0);
X if (!*actual_path) goto root_dir;
X if ((rval = Fsfirst("*.*", FA_DIR)) < 0) {
X errno = -rval;
X return -1;
X }
X if (dots == 2 && (rval = Fsnext()) < 0) {
X errno = -rval;
X return -1;
X }
X if (strcmp(path, dtabuf.dta_name)) {
X errno = ENOENT;
X return -1;
X }
X } else {
X /* Optimization: if the file is already found in an open dir */
X /* use information collected there instead of Fsfirst() */
X char *cp;
X char buf[MAXPATHLEN+1];
X DIR *dp;
X struct _dircontents *dc;
X
X strcpy(buf, path);
X cp = rindex(buf, '\\');
X if(cp) *cp++ = '\0';
X else {
X /* we are searching in '.' */
X cp = path;
X Dgetpath(buf, 0);
X }
X /* now we have the directory component in buf */
X for(dp = _current_open_directory; dp; dp = dp->dd_next) {
X if(!strcmp(dp->dd_name, buf)) { /* WOW!, we got it */
X for(dc = dp->dd_contents;dc;dc = dc->_d_next) {
X if(!strcmp(cp,dc->_d_entry)) {
X dtabuf.dta_attribute = dc->_d_attr;
X dtabuf.dta_date = dc->_d_date;
X dtabuf.dta_time = dc->_d_time;
X dtabuf.dta_size = dc->_d_size;
X goto got_dta;;
X }
X }
X }
X }
X if ((rval = Fsfirst(path, FA_SYSTEM|FA_HIDDEN|FA_DIR)) < 0) {
X errno = -rval;
X return -1;
X }
X }
Xgot_dta:
X st->st_ino = ++inode; /* should be able to do better then this */
X st->st_mode = 0644 | (dtabuf.dta_attribute & FA_DIR ?
X S_IFDIR | 0111 : S_IFREG);
X if(dtabuf.dta_attribute & FA_RDONLY) st->st_mode &= ~0222;
X if(dtabuf.dta_attribute & FA_HIDDEN) st->st_mode &= ~0444;
X st->st_mtime = st->st_ctime = st->st_atime =
X _time(0L, (dtabuf.dta_date << 16) | dtabuf.dta_time);
X st->st_attr = dtabuf.dta_attribute;
X if (st->st_mode & S_IFREG) {
X if ((fd = Fopen(path,0)) < 0) {
X errno = -rval;
X return -1;
X }
X Fread(fd,2,&magic);
X Fclose(fd);
X if (magic == 0x601A) st->st_mode |= 0111;
X st->st_size = dtabuf.dta_size;
X st->st_blocks = (dtabuf.dta_size + 1023) / 1024;
X } else {
Xfill_in:
X st->st_size = 1024;
X st->st_blocks = 1;
X }
X if (*path && path[1] == ':')
X st->st_dev = islower(*path) ? *path - 'a' : *path - 'A';
X else
X st->st_dev = Dgetdrv();
X st->st_rdev = 0;
X st->st_nlink = 1;
X st->st_uid = 0;
X st->st_gid = 0;
X st->st_blksize = 1024;
X return 0;
X}
END_OF_FILE
if test 4534 -ne `wc -c <'stat.c'`; then
echo shar: \"'stat.c'\" unpacked with wrong size!
fi
# end of 'stat.c'
fi
if test -f 'system.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'system.c'\"
else
echo shar: Extracting \"'system.c'\" \(3327 characters\)
sed "s/^X//" >'system.c' <<'END_OF_FILE'
X/* 9.8.1989 (er) changed return values of m_getenv() and g_getline(), to
X * minimize program size (this file is contained in every
X * program because of signal(SIGTSTP))
X * registers d1-a5 are now saved before a system call (not
X * necessary in m_getenv since Master will do this)
X */
X#include <osbind.h>
X#include <time.h>
X
Xstatic long (*shell_p)();
Xextern int errno;
Xclock_t _sys_runtime;
Xchar _shell_is_running = 0;
X
Xstatic void
Xread_shell(void)
X{
X long *_shell_p = (long *) 0x4F6L;
X
X shell_p = (long (*)())(*_shell_p);
X}
X
X/* This reads the _shell_p vector and tries to determine what kind */
X/* of shell we have running - !!! PLEASE ADD NEW MAGIC NUMBERS !!! */
Xstatic int
Xinit_system(void)
X{
X int ret;
X
X Supexec(read_shell);
X if(!(long)shell_p) return(0);
X ret = 1;
X if((*((long *)(((long) shell_p)-10)) == 0x00420135L))
X ret = 2; /* Gulam */
X if((*((long *)(((long) shell_p)-4)) == 0xCDCEC5D2L) || /* Master 5.0 */
X (*((long *)(((long) shell_p)-8)) == 0x4D415354L)) /* Master 5.4 */
X ret = 3; /* Master */
X return(ret);
X}
X
X/* this function executes the given command cmd by the shell at _shell_p */
X/* if cmd == NULL only the presence of a shell (and it's type) is reported */
X/* when we want an interactive shell (cmd == "-i") then substitute this to */
X/* "" if the shell is Gulam - we could also Pexec("$SHELL") if there is no */
X/* shell at _shell_p */
Xint
Xsystem(const char *cmd)
X{
X int ret;
X clock_t start_time;
X
X switch(ret = init_system()) {
X case 0 : return(0);
X case 2 : if (!strcmp(cmd,"-i")) cmd = "ue";
X default: if (cmd) {
X start_time = clock();
X _shell_is_running = 1;
X asm("moveml d1-a5, sp@-");
X asm("movel %0, sp@-" :: "g" (cmd));
X (void) (shell_p[0])();
X asm("addql #4, sp");
X asm("moveml sp@+, d1-a5");
X asm volatile ("movel d0, %0" : "=g" (ret));
X _shell_is_running = 0;
X _sys_runtime += clock() - start_time;
X if(ret < 0) errno = -ret;
X }
X return(ret);
X }
X /*NOTREACHED*/
X}
X
X/* special system call if the shell is Master 5.x */
X/* we ask for the expansion of the shell variable var, if Master is not */
X/* running we return with the expansion as environment var - we could also */
X/* get shell vars from other shells with output redirection like this one: */
X/* system("echo $var > var.tmp") and then read this file if we got no error */
Xchar *
Xm_getenv(const char *var)
X{
X extern long getenv();
X char *result;
X
X if(init_system() == 3) {
X _shell_is_running = 1;
X result = (char *) (shell_p[4])(1L,var);
X _shell_is_running = 0;
X } else result = ""; /* getenv(var); */
X return(result);
X}
X
X/* special system call if the shell is Gulam */
X/* we ask for a line of input provided by the shell (with all usual */
X/* editing), if Gulam is not running we simply read a line from stdin */
X/* we could also use system("ask \"\" tmpvar") and then get the value */
X/* of $tmpvar with m_getenv("tmpvar") if the shell is Master */
Xvoid
Xg_getline(char *line)
X{
X void (*func)(void);
X
X if(!line) return;
X if(init_system() != 2) *line = '\0'; /* read(0,line,256); */
X else {
X _shell_is_running = 1;
X func = (void (*)(void))&(shell_p[-6]);
X asm("moveml d1-a5, sp@-");
X asm("movel %0, sp@-" :: "g" (line));
X (*func)(); /* the argument is already on the stack */
X asm("addql #4, sp");
X asm("moveml sp@+, d1-a5");
X _shell_is_running = 0;
X }
X}
END_OF_FILE
if test 3327 -ne `wc -c <'system.c'`; then
echo shar: \"'system.c'\" unpacked with wrong size!
fi
# end of 'system.c'
fi
if test -f 'timer.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'timer.c'\"
else
echo shar: Extracting \"'timer.c'\" \(3923 characters\)
sed "s/^X//" >'timer.c' <<'END_OF_FILE'
X/*
X * Cross Development System for Atari ST
X * Copyright (c) 1988, Memorial University of Newfoundland
X *
X * This routine uses the vertical blank interrupt queue to get it's timing
X * done. This means that it probably depends on the resolution of the screen.
X * If there is no room in the vbl queue then -1 is returned. Note that
X * before the program terminates, this routine must be taken out of the
X * queue - to do this, _unalarm() is called from exit(). If alarm() is
X * not used in the program, the _unalarm() routine is a null one.
X * This routine works by messing with the return pc (and sr) on the stack
X * when it gets called from the vbl interupt routine. Also, the routine
X * checks to make sure a trap is not in progress by checking the __in_trap
X * variable (which *must* be set to one before a trap is done, and cleared
X * afer by the programmer - this is normally handled by the __*bios routines).
X * All this weirdness is done to ensure that the os is not disturbed while
X * it is doing stuff - therefor it is safe to do a longjmp() inside a signal
X * handling routine.
X *
X * $Header: alarm.c,v 1.1 88/02/03 22:37:51 m68k Exp $
X *
X * added SIGHUP, _init_timer and _exit_timer (called from crt0.s) (er)
X * renamed to timer.c and included clock()-function (er)
X *
X * $Log: alarm.c,v $
X * Revision 1.1 88/02/03 22:37:51 m68k
X * Initial revision
X *
X */
X#include <osbind.h>
X#include <sysvars.h>
X#include <signal.h>
X#include <time.h>
X
X#define HZ (70) /* how often we get called a second */
X#define CLK_VEC 0x100 /* the clock vector */
X
Xtypedef long *long_ptr;
X
Xextern volatile int _received_signal; /* in alrm_nasty.s */
Xextern char _shell_is_running; /* in system.c */
Xextern const long _base;
Xextern const long_ptr _act_pd;
X
Xstatic int alarm_timer();
Xextern int _exit_timer();
Xextern int _init_timer();
Xstatic int remove_timer();
Xstatic int install_timer();
X
Xclock_t _start_time = 0L;
X
Xstatic int
X_clock(void)
X{
X return *((clock_t *)_hz_200);
X}
X
Xclock_t
Xclock(void)
X{
X return (Supexec(_clock) - _start_time);
X}
X
Xstatic int carrier_was_on = 0;
Xstatic long alarmtime = 0;
Xstatic clock_t trigger = (clock_t) 0;
X
Xint
Xalarm(int n)
X{
X long oldticks;
X
X trigger = (clock_t) 0; /* block alarms now */
X oldticks = alarmtime;
X alarmtime = n; /* that's the new one */
X if(n) trigger = Supexec(_clock) + n * CLK_TCK; /* and go */
X return oldticks;
X}
X
Xint
X_init_timer(void)
X{
X return Supexec(install_timer);
X}
X
Xint
X_exit_timer(void)
X{
X return Supexec(remove_timer);
X}
X
X/*
X * This routine should be as small as possible as it is called lots of times
X * (There isn't really an argument - it's just there so we can get the
X * address of the stack)
X * If we just received another signal don't do anything - just wait until it's
X * being processed. (er)
X */
Xasm(".ascii \"XBRAGNUC\""); /* protocoll */
Xasm(".long 0"); /* old vector == no vector */
X
Xstatic int
Xalarm_timer(int arg)
X{
X if(_shell_is_running || *_act_pd != _base || _received_signal)
X return 0; /* too dangerous to process signals */
X if (trigger && *((clock_t *)_hz_200) > trigger) {
X /* rrriiinnnngggggggg! */
X alarmtime = trigger = 0;
X _received_signal = SIGALRM;
X _alrm_nasty(&arg);
X } else {
X int carrier_is_off = (*(char *) 0x00FFFA01L) & 2;
X
X if (carrier_was_on && carrier_is_off) {
X carrier_was_on = 0;
X _received_signal = SIGHUP;
X _alrm_nasty(&arg);
X } else carrier_was_on = !carrier_is_off;
X }
X return 0;
X}
X
X/* These routines must be called in super mode */
Xstatic int
Xremove_timer(void)
X{
X char **func;
X int i;
X
X trigger = (clock_t) 0; /* no more alarms now */
X func = *_vblqueue;
X i = *nvblq;
X while (i--)
X if (*func == (char *) alarm_timer) {
X *func = (char *) 0;
X return 0;
X } else func++;
X return 1;
X}
X
Xstatic int
Xinstall_timer(void)
X{
X char **func;
X int i;
X
X func = *_vblqueue;
X i = *nvblq;
X while (i--)
X if (!*func) {
X *func = (char *) alarm_timer;
X return 0;
X } else func++;
X return 1;
X}
END_OF_FILE
if test 3923 -ne `wc -c <'timer.c'`; then
echo shar: \"'timer.c'\" unpacked with wrong size!
fi
# end of 'timer.c'
fi
echo shar: End of archive 4 \(of 7\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 7 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0