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