Research V7 development
authorDennis Ritchie <dmr@research.uucp>
Wed, 10 Jan 1979 19:58:57 +0000 (14:58 -0500)
committerDennis Ritchie <dmr@research.uucp>
Wed, 10 Jan 1979 19:58:57 +0000 (14:58 -0500)
Work on file usr/src/libc/gen/timezone.c
Work on file usr/src/libc/gen/execvp.c
Work on file usr/src/libc/gen/cuexit.s
Work on file usr/src/libc/gen/getlogin.c
Work on file usr/src/libc/gen/getenv.c
Work on file usr/src/libc/gen/perror.c
Work on file usr/src/libc/gen/sleep.c
Work on file usr/src/libc/gen/ttyslot.c
Work on file usr/src/libc/gen/abort.s
Work on file usr/src/libc/gen/ttyname.c
Work on file usr/src/libc/gen/abs.c
Work on file usr/src/libc/gen/atol.c
Work on file usr/src/libc/gen/atoi.c
Work on file usr/src/libc/gen/ctime.c
Work on file usr/src/libc/gen/calloc.c
Work on file usr/src/libc/gen/ecvt.c
Work on file usr/src/libc/gen/malloc.c
Work on file usr/src/libc/gen/fakfp.s
Work on file usr/src/libc/gen/fakcu.s
Work on file usr/src/libc/gen/errlst.c
Work on file usr/src/libc/gen/isatty.c
Work on file usr/src/libc/gen/frexp11.s
Work on file usr/src/libc/gen/l3.c
Work on file usr/src/libc/gen/mktemp.c
Work on file usr/src/libc/gen/ldexp11.s
Work on file usr/src/libc/gen/ldfps.s
Work on file usr/src/libc/gen/mon.c
Work on file usr/src/libc/gen/modf11.s
Work on file usr/src/libc/gen/nlist.c
Work on file usr/src/libc/gen/stty.c
Work on file usr/src/libc/gen/rand.c
Work on file usr/src/libc/gen/setjmp.s

Synthesized-from: v7

32 files changed:
usr/src/libc/gen/abort.s [new file with mode: 0644]
usr/src/libc/gen/abs.c [new file with mode: 0644]
usr/src/libc/gen/atoi.c [new file with mode: 0644]
usr/src/libc/gen/atol.c [new file with mode: 0644]
usr/src/libc/gen/calloc.c [new file with mode: 0644]
usr/src/libc/gen/ctime.c [new file with mode: 0644]
usr/src/libc/gen/cuexit.s [new file with mode: 0644]
usr/src/libc/gen/ecvt.c [new file with mode: 0644]
usr/src/libc/gen/errlst.c [new file with mode: 0644]
usr/src/libc/gen/execvp.c [new file with mode: 0644]
usr/src/libc/gen/fakcu.s [new file with mode: 0644]
usr/src/libc/gen/fakfp.s [new file with mode: 0644]
usr/src/libc/gen/frexp11.s [new file with mode: 0644]
usr/src/libc/gen/getenv.c [new file with mode: 0644]
usr/src/libc/gen/getlogin.c [new file with mode: 0644]
usr/src/libc/gen/isatty.c [new file with mode: 0644]
usr/src/libc/gen/l3.c [new file with mode: 0644]
usr/src/libc/gen/ldexp11.s [new file with mode: 0644]
usr/src/libc/gen/ldfps.s [new file with mode: 0644]
usr/src/libc/gen/malloc.c [new file with mode: 0644]
usr/src/libc/gen/mktemp.c [new file with mode: 0644]
usr/src/libc/gen/modf11.s [new file with mode: 0644]
usr/src/libc/gen/mon.c [new file with mode: 0644]
usr/src/libc/gen/nlist.c [new file with mode: 0644]
usr/src/libc/gen/perror.c [new file with mode: 0644]
usr/src/libc/gen/rand.c [new file with mode: 0644]
usr/src/libc/gen/setjmp.s [new file with mode: 0644]
usr/src/libc/gen/sleep.c [new file with mode: 0644]
usr/src/libc/gen/stty.c [new file with mode: 0644]
usr/src/libc/gen/timezone.c [new file with mode: 0644]
usr/src/libc/gen/ttyname.c [new file with mode: 0644]
usr/src/libc/gen/ttyslot.c [new file with mode: 0644]

diff --git a/usr/src/libc/gen/abort.s b/usr/src/libc/gen/abort.s
new file mode 100644 (file)
index 0000000..6bdb9ad
--- /dev/null
@@ -0,0 +1,11 @@
+/ C library -- abort
+
+.globl _abort
+iot    = 4
+.globl csv,cret
+
+_abort:
+       jsr     r5,csv
+       iot
+       clr     r0
+       jmp     cret
diff --git a/usr/src/libc/gen/abs.c b/usr/src/libc/gen/abs.c
new file mode 100644 (file)
index 0000000..618e625
--- /dev/null
@@ -0,0 +1,7 @@
+abs(arg)
+{
+
+       if(arg < 0)
+               arg = -arg;
+       return(arg);
+}
diff --git a/usr/src/libc/gen/atoi.c b/usr/src/libc/gen/atoi.c
new file mode 100644 (file)
index 0000000..57c7ff1
--- /dev/null
@@ -0,0 +1,24 @@
+atoi(p)
+register char *p;
+{
+       register int n;
+       register int f;
+
+       n = 0;
+       f = 0;
+       for(;;p++) {
+               switch(*p) {
+               case ' ':
+               case '\t':
+                       continue;
+               case '-':
+                       f++;
+               case '+':
+                       p++;
+               }
+               break;
+       }
+       while(*p >= '0' && *p <= '9')
+               n = n*10 + *p++ - '0';
+       return(f? -n: n);
+}
diff --git a/usr/src/libc/gen/atol.c b/usr/src/libc/gen/atol.c
new file mode 100644 (file)
index 0000000..71ae769
--- /dev/null
@@ -0,0 +1,25 @@
+long
+atol(p)
+register char *p;
+{
+       long n;
+       register int f;
+
+       n = 0;
+       f = 0;
+       for(;;p++) {
+               switch(*p) {
+               case ' ':
+               case '\t':
+                       continue;
+               case '-':
+                       f++;
+               case '+':
+                       p++;
+               }
+               break;
+       }
+       while(*p >= '0' && *p <= '9')
+               n = n*10 + *p++ - '0';
+       return(f? -n: n);
+}
diff --git a/usr/src/libc/gen/calloc.c b/usr/src/libc/gen/calloc.c
new file mode 100644 (file)
index 0000000..52f46d4
--- /dev/null
@@ -0,0 +1,31 @@
+/*     calloc - allocate and clear memory block
+*/
+#define CHARPERINT (sizeof(int)/sizeof(char))
+#define NULL 0
+
+char *
+calloc(num, size)
+unsigned num, size;
+{
+       register char *mp;
+       char *malloc();
+       register int *q;
+       register m;
+
+       num *= size;
+       mp = malloc(num);
+       if(mp == NULL)
+               return(NULL);
+       q = (int *) mp;
+       m = (num+CHARPERINT-1)/CHARPERINT;
+       while(--m>=0)
+               *q++ = 0;
+       return(mp);
+}
+
+cfree(p, num, size)
+char *p;
+unsigned num, size;
+{
+       free(p);
+}
diff --git a/usr/src/libc/gen/ctime.c b/usr/src/libc/gen/ctime.c
new file mode 100644 (file)
index 0000000..cd8b9aa
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * This routine converts time as follows.
+ * The epoch is 0000 Jan 1 1970 GMT.
+ * The argument time is in seconds since then.
+ * The localtime(t) entry returns a pointer to an array
+ * containing
+ *  seconds (0-59)
+ *  minutes (0-59)
+ *  hours (0-23)
+ *  day of month (1-31)
+ *  month (0-11)
+ *  year-1970
+ *  weekday (0-6, Sun is 0)
+ *  day of the year
+ *  daylight savings flag
+ *
+ * The routine calls the system to determine the local
+ * timezone and whether Daylight Saving Time is permitted locally.
+ * (DST is then determined by the current US standard rules)
+ * There is a table that accounts for the peculiarities
+ * undergone by daylight time in 1974-1975.
+ *
+ * The routine does not work
+ * in Saudi Arabia which runs on Solar time.
+ *
+ * asctime(tvec))
+ * where tvec is produced by localtime
+ * returns a ptr to a character string
+ * that has the ascii time in the form
+ *     Thu Jan 01 00:00:00 1970n0\b\b\\
+ *     01234567890123456789012345
+ *     0         1         2
+ *
+ * ctime(t) just calls localtime, then asctime.
+ */
+
+#include <time.h>
+#include <sys/types.h>
+#include <sys/timeb.h>
+
+static char    cbuf[26];
+static int     dmsize[12] =
+{
+       31,
+       28,
+       31,
+       30,
+       31,
+       30,
+       31,
+       31,
+       30,
+       31,
+       30,
+       31
+};
+
+/*
+ * The following table is used for 1974 and 1975 and
+ * gives the day number of the first day after the Sunday of the
+ * change.
+ */
+static struct {
+       int     daylb;
+       int     dayle;
+} daytab[] = {
+       5,      333,    /* 1974: Jan 6 - last Sun. in Nov */
+       58,     303,    /* 1975: Last Sun. in Feb - last Sun in Oct */
+};
+
+struct tm      *gmtime();
+char           *ct_numb();
+struct tm      *localtime();
+char   *ctime();
+char   *ct_num();
+char   *asctime();
+
+char *
+ctime(t)
+long *t;
+{
+       return(asctime(localtime(t)));
+}
+
+struct tm *
+localtime(tim)
+long *tim;
+{
+       register int dayno;
+       register struct tm *ct;
+       register daylbegin, daylend;
+       long copyt;
+       struct timeb systime;
+
+       ftime(&systime);
+       copyt = *tim - (long)systime.timezone*60;
+       ct = gmtime(&copyt);
+       dayno = ct->tm_yday;
+       daylbegin = 119;        /* last Sun in Apr */
+       daylend = 303;          /* Last Sun in Oct */
+       if (ct->tm_year==74 || ct->tm_year==75) {
+               daylbegin = daytab[ct->tm_year-74].daylb;
+               daylend = daytab[ct->tm_year-74].dayle;
+       }
+       daylbegin = sunday(ct, daylbegin);
+       daylend = sunday(ct, daylend);
+       if (systime.dstflag &&
+           (dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) &&
+           (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) {
+               copyt += 1*60*60;
+               ct = gmtime(&copyt);
+               ct->tm_isdst++;
+       }
+       return(ct);
+}
+
+/*
+ * The argument is a 0-origin day number.
+ * The value is the day number of the first
+ * Sunday on or after the day.
+ */
+static
+sunday(t, d)
+register struct tm *t;
+register int d;
+{
+       if (d >= 58)
+               d += dysize(t->tm_year) - 365;
+       return(d - (d - t->tm_yday + t->tm_wday + 700) % 7);
+}
+
+struct tm *
+gmtime(tim)
+long *tim;
+{
+       register int d0, d1;
+       long hms, day;
+       register int *tp;
+       static struct tm xtime;
+
+       /*
+        * break initial number into days
+        */
+       hms = *tim % 86400;
+       day = *tim / 86400;
+       if (hms<0) {
+               hms += 86400;
+               day -= 1;
+       }
+       tp = (int *)&xtime;
+
+       /*
+        * generate hours:minutes:seconds
+        */
+       *tp++ = hms%60;
+       d1 = hms/60;
+       *tp++ = d1%60;
+       d1 /= 60;
+       *tp++ = d1;
+
+       /*
+        * day is the day number.
+        * generate day of the week.
+        * The addend is 4 mod 7 (1/1/1970 was Thursday)
+        */
+
+       xtime.tm_wday = (day+7340036)%7;
+
+       /*
+        * year number
+        */
+       if (day>=0) for(d1=70; day >= dysize(d1); d1++)
+               day -= dysize(d1);
+       else for (d1=70; day<0; d1--)
+               day += dysize(d1-1);
+       xtime.tm_year = d1;
+       xtime.tm_yday = d0 = day;
+
+       /*
+        * generate month
+        */
+
+       if (dysize(d1)==366)
+               dmsize[1] = 29;
+       for(d1=0; d0 >= dmsize[d1]; d1++)
+               d0 -= dmsize[d1];
+       dmsize[1] = 28;
+       *tp++ = d0+1;
+       *tp++ = d1;
+       xtime.tm_isdst = 0;
+       return(&xtime);
+}
+
+char *
+asctime(t)
+struct tm *t;
+{
+       register char *cp, *ncp;
+       register int *tp;
+
+       cp = cbuf;
+       for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;);
+       ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday];
+       cp = cbuf;
+       *cp++ = *ncp++;
+       *cp++ = *ncp++;
+       *cp++ = *ncp++;
+       cp++;
+       tp = &t->tm_mon;
+       ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3];
+       *cp++ = *ncp++;
+       *cp++ = *ncp++;
+       *cp++ = *ncp++;
+       cp = ct_numb(cp, *--tp);
+       cp = ct_numb(cp, *--tp+100);
+       cp = ct_numb(cp, *--tp+100);
+       cp = ct_numb(cp, *--tp+100);
+       if (t->tm_year>=100) {
+               cp[1] = '2';
+               cp[2] = '0';
+       }
+       cp += 2;
+       cp = ct_numb(cp, t->tm_year+100);
+       return(cbuf);
+}
+
+dysize(y)
+{
+       if((y%4) == 0)
+               return(366);
+       return(365);
+}
+
+static char *
+ct_numb(cp, n)
+register char *cp;
+{
+       cp++;
+       if (n>=10)
+               *cp++ = (n/10)%10 + '0';
+       else
+               *cp++ = ' ';
+       *cp++ = n%10 + '0';
+       return(cp);
+}
diff --git a/usr/src/libc/gen/cuexit.s b/usr/src/libc/gen/cuexit.s
new file mode 100644 (file)
index 0000000..f4ffb99
--- /dev/null
@@ -0,0 +1,16 @@
+/ C library -- exit
+
+/ exit(code)
+/ code is return in r0 to system
+
+.globl _exit
+.globl __cleanup
+exit = 1
+
+_exit:
+       mov     r5,-(sp)
+       mov     sp,r5
+       jsr     pc,__cleanup
+       mov     4(r5),r0
+       sys     exit
+
diff --git a/usr/src/libc/gen/ecvt.c b/usr/src/libc/gen/ecvt.c
new file mode 100644 (file)
index 0000000..43d17fc
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *     ecvt converts to decimal
+ *     the number of digits is specified by ndigit
+ *     decpt is set to the position of the decimal point
+ *     sign is set to 0 for positive, 1 for negative
+ */
+
+char   *cvt();
+
+#define        NDIG    80
+char*
+ecvt(arg, ndigits, decpt, sign)
+double arg;
+int ndigits, *decpt, *sign;
+{
+       return(cvt(arg, ndigits, decpt, sign, 1));
+}
+
+char*
+fcvt(arg, ndigits, decpt, sign)
+double arg;
+int ndigits, *decpt, *sign;
+{
+       return(cvt(arg, ndigits, decpt, sign, 0));
+}
+
+static char*
+cvt(arg, ndigits, decpt, sign, eflag)
+double arg;
+int ndigits, *decpt, *sign;
+{
+       register int r2;
+       double fi, fj;
+       register char *p, *p1;
+       static char buf[NDIG];
+       double modf();
+
+       if (ndigits<0)
+               ndigits = 0;
+       if (ndigits>=NDIG-1)
+               ndigits = NDIG-2;
+       r2 = 0;
+       *sign = 0;
+       p = &buf[0];
+       if (arg<0) {
+               *sign = 1;
+               arg = -arg;
+       }
+       arg = modf(arg, &fi);
+       p1 = &buf[NDIG];
+       /*
+        * Do integer part
+        */
+       if (fi != 0) {
+               p1 = &buf[NDIG];
+               while (fi != 0) {
+                       fj = modf(fi/10, &fi);
+                       *--p1 = (int)((fj+.03)*10) + '0';
+                       r2++;
+               }
+               while (p1 < &buf[NDIG])
+                       *p++ = *p1++;
+       } else if (arg > 0) {
+               while ((fj = arg*10) < 1) {
+                       arg = fj;
+                       r2--;
+               }
+       }
+       p1 = &buf[ndigits];
+       if (eflag==0)
+               p1 += r2;
+       *decpt = r2;
+       if (p1 < &buf[0]) {
+               buf[0] = '\0';
+               return(buf);
+       }
+       while (p<=p1 && p<&buf[NDIG]) {
+               arg *= 10;
+               arg = modf(arg, &fj);
+               *p++ = (int)fj + '0';
+       }
+       if (p1 >= &buf[NDIG]) {
+               buf[NDIG-1] = '\0';
+               return(buf);
+       }
+       p = p1;
+       *p1 += 5;
+       while (*p1 > '9') {
+               *p1 = '0';
+               if (p1>buf)
+                       ++*--p1;
+               else {
+                       *p1 = '1';
+                       (*decpt)++;
+                       if (eflag==0) {
+                               if (p>buf)
+                                       *p = '0';
+                               p++;
+                       }
+               }
+       }
+       *p = '\0';
+       return(buf);
+}
diff --git a/usr/src/libc/gen/errlst.c b/usr/src/libc/gen/errlst.c
new file mode 100644 (file)
index 0000000..a9770d5
--- /dev/null
@@ -0,0 +1,38 @@
+char   *sys_errlist[] = {
+       "Error 0",
+       "Not owner",
+       "No such file or directory",
+       "No such process",
+       "Interrupted system call",
+       "I/O error",
+       "No such device or address",
+       "Arg list too long",
+       "Exec format error",
+       "Bad file number",
+       "No children",
+       "No more processes",
+       "Not enough core",
+       "Permission denied",
+       "Bad address",
+       "Block device required",
+       "Mount device busy",
+       "File exists",
+       "Cross-device link",
+       "No such device",
+       "Not a directory",
+       "Is a directory",
+       "Invalid argument",
+       "File table overflow",
+       "Too many open files",
+       "Not a typewriter",
+       "Text file busy",
+       "File too large",
+       "No space left on device",
+       "Illegal seek",
+       "Read-only file system",
+       "Too many links",
+       "Broken pipe",
+       "Argument too large",
+       "Result too large",
+};
+int    sys_nerr = { sizeof sys_errlist/sizeof sys_errlist[0] };
diff --git a/usr/src/libc/gen/execvp.c b/usr/src/libc/gen/execvp.c
new file mode 100644 (file)
index 0000000..4942d5e
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *     execlp(name, arg,...,0) (like execl, but does path search)
+ *     execvp(name, argv)      (like execv, but does path search)
+ */
+#include <errno.h>
+#define        NULL    0
+
+static char shell[] =  "/bin/sh";
+char   *execat(), *getenv();
+extern errno;
+
+execlp(name, argv)
+char *name, *argv;
+{
+       return(execvp(name, &argv));
+}
+
+execvp(name, argv)
+char *name, **argv;
+{
+       char *pathstr;
+       register char *cp;
+       char fname[128];
+       char *newargs[256];
+       int i;
+       register unsigned etxtbsy = 1;
+       register eacces = 0;
+
+       if ((pathstr = getenv("PATH")) == NULL)
+               pathstr = ":/bin:/usr/bin";
+       cp = index(name, '/')? "": pathstr;
+
+       do {
+               cp = execat(cp, name, fname);
+       retry:
+               execv(fname, argv);
+               switch(errno) {
+               case ENOEXEC:
+                       newargs[0] = "sh";
+                       newargs[1] = fname;
+                       for (i=1; newargs[i+1]=argv[i]; i++) {
+                               if (i>=254) {
+                                       errno = E2BIG;
+                                       return(-1);
+                               }
+                       }
+                       execv(shell, newargs);
+                       return(-1);
+               case ETXTBSY:
+                       if (++etxtbsy > 5)
+                               return(-1);
+                       sleep(etxtbsy);
+                       goto retry;
+               case EACCES:
+                       eacces++;
+                       break;
+               case ENOMEM:
+               case E2BIG:
+                       return(-1);
+               }
+       } while (cp);
+       if (eacces)
+               errno = EACCES;
+       return(-1);
+}
+
+static char *
+execat(s1, s2, si)
+register char *s1, *s2;
+char *si;
+{
+       register char *s;
+
+       s = si;
+       while (*s1 && *s1 != ':' && *s1 != '-')
+               *s++ = *s1++;
+       if (si != s)
+               *s++ = '/';
+       while (*s2)
+               *s++ = *s2++;
+       *s = '\0';
+       return(*s1? ++s1: 0);
+}
diff --git a/usr/src/libc/gen/fakcu.s b/usr/src/libc/gen/fakcu.s
new file mode 100644 (file)
index 0000000..f8d74f6
--- /dev/null
@@ -0,0 +1,7 @@
+/
+/ dummy cleanup routine if none supplied by user.
+
+.globl __cleanup
+
+__cleanup:
+       rts     pc
diff --git a/usr/src/libc/gen/fakfp.s b/usr/src/libc/gen/fakfp.s
new file mode 100644 (file)
index 0000000..6af0922
--- /dev/null
@@ -0,0 +1,12 @@
+/ fakefp -- fake floating point simulator
+
+.globl fptrap
+signal = 48.
+rti = 2
+
+fptrap:
+       sub     $2,(sp)
+       mov     r0,-(sp)
+       sys     signal; 4; 0
+       mov     (sp)+,r0
+       rti
diff --git a/usr/src/libc/gen/frexp11.s b/usr/src/libc/gen/frexp11.s
new file mode 100644 (file)
index 0000000..46fc518
--- /dev/null
@@ -0,0 +1,16 @@
+/  double frexp(x, ip)
+/  double x; int *ip;
+/  returns a fractional part 1/16 <= |value| < 1
+/ and stores an exponent so x = value * 2^(*ip)
+
+.globl _frexp
+.globl csv, cret
+
+_frexp:
+       jsr     r5,csv
+       movf    4(r5),fr0
+       movei   fr0,r0
+       clr     r1
+       movie   r1,fr0
+       mov     r0,*12.(r5)
+       jmp     cret
diff --git a/usr/src/libc/gen/getenv.c b/usr/src/libc/gen/getenv.c
new file mode 100644 (file)
index 0000000..8fb727e
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *     getenv(name)
+ *     returns ptr to value associated with name, if any, else NULL
+ */
+#define NULL   0
+extern char **environ;
+char   *nvmatch();
+
+char *
+getenv(name)
+register char *name;
+{
+       register char **p = environ;
+       register char *v;
+
+       while (*p != NULL)
+               if ((v = nvmatch(name, *p++)) != NULL)
+                       return(v);
+       return(NULL);
+}
+
+/*
+ *     s1 is either name, or name=value
+ *     s2 is name=value
+ *     if names match, return value of s2, else NULL
+ *     used for environment searching: see getenv
+ */
+
+static char *
+nvmatch(s1, s2)
+register char *s1, *s2;
+{
+
+       while (*s1 == *s2++)
+               if (*s1++ == '=')
+                       return(s2);
+       if (*s1 == '\0' && *(s2-1) == '=')
+               return(s2);
+       return(NULL);
+}
diff --git a/usr/src/libc/gen/getlogin.c b/usr/src/libc/gen/getlogin.c
new file mode 100644 (file)
index 0000000..f8a8c1c
--- /dev/null
@@ -0,0 +1,25 @@
+#include <utmp.h>
+
+static char    UTMP[]  = "/etc/utmp";
+static struct  utmp ubuf;
+
+char *
+getlogin()
+{
+       register me, uf;
+       register char *cp;
+
+       if( !(me = ttyslot()) )
+               return(0);
+       if( (uf = open( UTMP, 0 )) < 0 )
+               return(0);
+       lseek( uf, (long)(me*sizeof(ubuf)), 0 );
+       if (read(uf, (char *)&ubuf, sizeof(ubuf)) != sizeof(ubuf))
+               return(0);
+       close(uf);
+       ubuf.ut_name[8] = ' ';
+       for (cp=ubuf.ut_name; *cp++!=' ';)
+               ;
+       *--cp = '\0';
+       return( ubuf.ut_name );
+}
diff --git a/usr/src/libc/gen/isatty.c b/usr/src/libc/gen/isatty.c
new file mode 100644 (file)
index 0000000..0743e62
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Returns 1 iff file is a tty
+ */
+
+#include <sgtty.h>
+
+isatty(f)
+{
+       struct sgttyb ttyb;
+
+       if (gtty(f, &ttyb) < 0)
+               return(0);
+       return(1);
+}
diff --git a/usr/src/libc/gen/l3.c b/usr/src/libc/gen/l3.c
new file mode 100644 (file)
index 0000000..623f9c9
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Convert longs to and from 3-byte disk addresses
+ */
+ltol3(cp, lp, n)
+char   *cp;
+long   *lp;
+int    n;
+{
+       register i;
+       register char *a, *b;
+
+       a = cp;
+       b = (char *)lp;
+       for(i=0;i<n;i++) {
+#ifdef interdata
+               b++;
+               *a++ = *b++;
+               *a++ = *b++;
+               *a++ = *b++;
+#else
+               *a++ = *b++;
+               b++;
+               *a++ = *b++;
+               *a++ = *b++;
+#endif
+       }
+}
+
+l3tol(lp, cp, n)
+long   *lp;
+char   *cp;
+int    n;
+{
+       register i;
+       register char *a, *b;
+
+       a = (char *)lp;
+       b = cp;
+       for(i=0;i<n;i++) {
+#ifdef interdata
+               *a++ = 0;
+               *a++ = *b++;
+               *a++ = *b++;
+               *a++ = *b++;
+#else
+               *a++ = *b++;
+               *a++ = 0;
+               *a++ = *b++;
+               *a++ = *b++;
+#endif
+       }
+}
diff --git a/usr/src/libc/gen/ldexp11.s b/usr/src/libc/gen/ldexp11.s
new file mode 100644 (file)
index 0000000..1abb9d5
--- /dev/null
@@ -0,0 +1,31 @@
+/ double ldexp(number, exp)
+/ double number
+/  -- returns number * 2^exp
+
+.globl _ldexp
+.globl csv, cret
+
+ERANGE = 34.
+
+_ldexp:
+       jsr     r5,csv
+       movf    4(r5),fr0
+       movei   fr0,r0
+       add     12.(r5),r0
+       movie   r0,fr0
+       cfcc
+       bvc     1f
+       bmi     2f
+       movf    huge,fr0
+       br      3f
+2:
+       movf    huge,fr0
+       negf    fr0
+3:
+       mov     $ERANGE,_errno
+1:
+       jmp     cret
+
+       .comm   _errno,2
+       .data
+huge:  077777; 0177776; 0177777; 0177777
diff --git a/usr/src/libc/gen/ldfps.s b/usr/src/libc/gen/ldfps.s
new file mode 100644 (file)
index 0000000..800cf62
--- /dev/null
@@ -0,0 +1,11 @@
+ldfps = 170100^tst
+/
+/ ldfps(number);
+
+.globl _ldfps
+_ldfps:
+       mov     r5,-(sp)
+       mov     sp,r5
+       ldfps   4(r5)
+       mov     (sp)+,r5
+       rts     pc
diff --git a/usr/src/libc/gen/malloc.c b/usr/src/libc/gen/malloc.c
new file mode 100644 (file)
index 0000000..a3df623
--- /dev/null
@@ -0,0 +1,189 @@
+#ifdef debug
+#define ASSERT(p) if(!(p))botch("p");else
+botch(s)
+char *s;
+{
+       printf("assertion botched: %s\n",s);
+       abort();
+}
+#else
+#define ASSERT(p)
+#endif
+
+/*     avoid break bug */
+#ifdef pdp11
+#define GRANULE 64
+#else
+#define GRANULE 0
+#endif
+/*     C storage allocator
+ *     circular first-fit strategy
+ *     works with noncontiguous, but monotonically linked, arena
+ *     each block is preceded by a ptr to the (pointer of) 
+ *     the next following block
+ *     blocks are exact number of words long 
+ *     aligned to the data type requirements of ALIGN
+ *     pointers to blocks must have BUSY bit 0
+ *     bit in ptr is 1 for busy, 0 for idle
+ *     gaps in arena are merely noted as busy blocks
+ *     last block of arena (pointed to by alloct) is empty and
+ *     has a pointer to first
+ *     idle blocks are coalesced during space search
+ *
+ *     a different implementation may need to redefine
+ *     ALIGN, NALIGN, BLOCK, BUSY, INT
+ *     where INT is integer type to which a pointer can be cast
+*/
+#define INT int
+#define ALIGN int
+#define NALIGN 1
+#define WORD sizeof(union store)
+#define BLOCK 1024     /* a multiple of WORD*/
+#define BUSY 1
+#define NULL 0
+#define testbusy(p) ((INT)(p)&BUSY)
+#define setbusy(p) (union store *)((INT)(p)|BUSY)
+#define clearbusy(p) (union store *)((INT)(p)&~BUSY)
+
+union store { union store *ptr;
+             ALIGN dummy[NALIGN];
+             int calloc;       /*calloc clears an array of integers*/
+};
+
+static union store allocs[2];  /*initial arena*/
+static union store *allocp;    /*search ptr*/
+static union store *alloct;    /*arena top*/
+static union store *allocx;    /*for benefit of realloc*/
+char   *sbrk();
+
+char *
+malloc(nbytes)
+unsigned nbytes;
+{
+       register union store *p, *q;
+       register nw;
+       static temp;    /*coroutines assume no auto*/
+
+       if(allocs[0].ptr==0) {  /*first time*/
+               allocs[0].ptr = setbusy(&allocs[1]);
+               allocs[1].ptr = setbusy(&allocs[0]);
+               alloct = &allocs[1];
+               allocp = &allocs[0];
+       }
+       nw = (nbytes+WORD+WORD-1)/WORD;
+       ASSERT(allocp>=allocs && allocp<=alloct);
+       ASSERT(allock());
+       for(p=allocp; ; ) {
+               for(temp=0; ; ) {
+                       if(!testbusy(p->ptr)) {
+                               while(!testbusy((q=p->ptr)->ptr)) {
+                                       ASSERT(q>p&&q<alloct);
+                                       p->ptr = q->ptr;
+                               }
+                               if(q>=p+nw && p+nw>=p)
+                                       goto found;
+                       }
+                       q = p;
+                       p = clearbusy(p->ptr);
+                       if(p>q)
+                               ASSERT(p<=alloct);
+                       else if(q!=alloct || p!=allocs) {
+                               ASSERT(q==alloct&&p==allocs);
+                               return(NULL);
+                       } else if(++temp>1)
+                               break;
+               }
+               temp = ((nw+BLOCK/WORD)/(BLOCK/WORD))*(BLOCK/WORD);
+               q = (union store *)sbrk(0);
+               if(q+temp+GRANULE < q) {
+                       return(NULL);
+               }
+               q = (union store *)sbrk(temp*WORD);
+               if((INT)q == -1) {
+                       return(NULL);
+               }
+               ASSERT(q>alloct);
+               alloct->ptr = q;
+               if(q!=alloct+1)
+                       alloct->ptr = setbusy(alloct->ptr);
+               alloct = q->ptr = q+temp-1;
+               alloct->ptr = setbusy(allocs);
+       }
+found:
+       allocp = p + nw;
+       ASSERT(allocp<=alloct);
+       if(q>allocp) {
+               allocx = allocp->ptr;
+               allocp->ptr = p->ptr;
+       }
+       p->ptr = setbusy(allocp);
+       return((char *)(p+1));
+}
+
+/*     freeing strategy tuned for LIFO allocation
+*/
+free(ap)
+register char *ap;
+{
+       register union store *p = (union store *)ap;
+
+       ASSERT(p>clearbusy(allocs[1].ptr)&&p<=alloct);
+       ASSERT(allock());
+       allocp = --p;
+       ASSERT(testbusy(p->ptr));
+       p->ptr = clearbusy(p->ptr);
+       ASSERT(p->ptr > allocp && p->ptr <= alloct);
+}
+
+/*     realloc(p, nbytes) reallocates a block obtained from malloc()
+ *     and freed since last call of malloc()
+ *     to have new size nbytes, and old content
+ *     returns new location, or 0 on failure
+*/
+
+char *
+realloc(p, nbytes)
+register union store *p;
+unsigned nbytes;
+{
+       register union store *q;
+       union store *s, *t;
+       register unsigned nw;
+       unsigned onw;
+
+       if(testbusy(p[-1].ptr))
+               free((char *)p);
+       onw = p[-1].ptr - p;
+       q = (union store *)malloc(nbytes);
+       if(q==NULL || q==p)
+               return((char *)q);
+       s = p;
+       t = q;
+       nw = (nbytes+WORD-1)/WORD;
+       if(nw<onw)
+               onw = nw;
+       while(onw--!=0)
+               *t++ = *s++;
+       if(q<p && q+nw>=p)
+               (q+(q+nw-p))->ptr = allocx;
+       return((char *)q);
+}
+
+#ifdef debug
+allock()
+{
+#ifdef longdebug
+       register union store *p;
+       int x;
+       x = 0;
+       for(p= &allocs[0]; clearbusy(p->ptr) > p; p=clearbusy(p->ptr)) {
+               if(p==allocp)
+                       x++;
+       }
+       ASSERT(p==alloct);
+       return(x==1|p==allocp);
+#else
+       return(1);
+#endif
+}
+#endif
diff --git a/usr/src/libc/gen/mktemp.c b/usr/src/libc/gen/mktemp.c
new file mode 100644 (file)
index 0000000..164e9af
--- /dev/null
@@ -0,0 +1,26 @@
+char *
+mktemp(as)
+char *as;
+{
+       register char *s;
+       register unsigned pid;
+       register i;
+
+       pid = getpid();
+       s = as;
+       while (*s++)
+               ;
+       s--;
+       while (*--s == 'X') {
+               *s = (pid%10) + '0';
+               pid /= 10;
+       }
+       s++;
+       i = 'a';
+       while (access(as, 0) != -1) {
+               if (i=='z')
+                       return("/");
+               *s = i++;
+       }
+       return(as);
+}
diff --git a/usr/src/libc/gen/modf11.s b/usr/src/libc/gen/modf11.s
new file mode 100644 (file)
index 0000000..cec82ca
--- /dev/null
@@ -0,0 +1,15 @@
+/ double modf(x, *fp)
+/ double x, *fp;
+/ return fractional part
+/ stash integer part (as double)
+
+.globl _modf
+.globl csv, cret
+one    = 040200
+
+_modf:
+       jsr     r5,csv
+       movf    4(r5),fr0
+       modf    $one,fr0
+       movf    fr1,*12.(r5)
+       jmp     cret
diff --git a/usr/src/libc/gen/mon.c b/usr/src/libc/gen/mon.c
new file mode 100644 (file)
index 0000000..eacafdf
--- /dev/null
@@ -0,0 +1,30 @@
+monitor(lowpc, highpc, buf, bufsiz, cntsiz)
+char *lowpc, *highpc;
+int *buf, bufsiz;
+{
+       register o;
+       static *sbuf, ssiz;
+
+       if (lowpc == 0) {
+               profil(0, 0, 0, 0);
+               o = creat("mon.out", 0666);
+               write(o, sbuf, ssiz<<1);
+               close(o);
+               return;
+       }
+       ssiz = bufsiz;
+       buf[0] = (int)lowpc;
+       buf[1] = (int)highpc;
+       buf[2] = cntsiz;
+       sbuf = buf;
+       buf += 3*(cntsiz+1);
+       bufsiz -= 3*(cntsiz+1);
+       if (bufsiz<=0)
+               return;
+       o = ((highpc - lowpc)>>1) & 077777;
+       if(bufsiz < o)
+               o = ((long)bufsiz<<15) / o;
+       else
+               o = 077777;
+       profil(buf, bufsiz<<1, lowpc, o<<1);
+}
diff --git a/usr/src/libc/gen/nlist.c b/usr/src/libc/gen/nlist.c
new file mode 100644 (file)
index 0000000..3701df7
--- /dev/null
@@ -0,0 +1,54 @@
+#include <a.out.h>
+int a_magic[] = {A_MAGIC1, A_MAGIC2, A_MAGIC3, A_MAGIC4, 0};
+#define SPACE 100              /* number of symbols read at a time */
+
+nlist(name, list)
+char *name;
+struct nlist *list;
+{
+       register struct nlist *p, *q;
+       int f, n, m, i;
+       long sa;
+       struct exec buf;
+       struct nlist space[SPACE];
+
+       for(p = list; p->n_name[0]; p++) {
+               p->n_type = 0;
+               p->n_value = 0;
+       }
+       f = open(name, 0);
+       if(f < 0)
+               return(-1);
+       read(f, (char *)&buf, sizeof buf);
+       for(i=0; a_magic[i]; i++)
+               if(a_magic[i] == buf.a_magic) break;
+       if(a_magic[i] == 0){
+               close(f);
+               return(-1);
+       }
+       sa = buf.a_text + (long)buf.a_data;
+       if(buf.a_flag != 1) sa *= 2;
+       sa += sizeof buf;
+       lseek(f, sa, 0);
+       n = buf.a_syms;
+
+       while(n){
+               m = sizeof space;
+               if(n < sizeof space)
+                       m = n;
+               read(f, (char *)space, m);
+               n -= m;
+               for(q = space; (m -= sizeof(struct nlist)) >= 0; q++) {
+                       for(p = list; p->n_name[0]; p++) {
+                               for(i=0;i<8;i++)
+                                       if(p->n_name[i] != q->n_name[i]) goto cont;
+                               p->n_value = q->n_value;
+                               p->n_type = q->n_type;
+                               break;
+               cont:           ;
+                       }
+               }
+       }
+       close(f);
+       return(0);
+}
diff --git a/usr/src/libc/gen/perror.c b/usr/src/libc/gen/perror.c
new file mode 100644 (file)
index 0000000..39c1cc9
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Print the error indicated
+ * in the cerror cell.
+ */
+
+int    errno;
+int    sys_nerr;
+char   *sys_errlist[];
+perror(s)
+char *s;
+{
+       register char *c;
+       register n;
+
+       c = "Unknown error";
+       if(errno < sys_nerr)
+               c = sys_errlist[errno];
+       n = strlen(s);
+       if(n) {
+               write(2, s, n);
+               write(2, ": ", 2);
+       }
+       write(2, c, strlen(c));
+       write(2, "\n", 1);
+}
diff --git a/usr/src/libc/gen/rand.c b/usr/src/libc/gen/rand.c
new file mode 100644 (file)
index 0000000..01afa99
--- /dev/null
@@ -0,0 +1,12 @@
+static long    randx = 1;
+
+srand(x)
+unsigned x;
+{
+       randx = x;
+}
+
+rand()
+{
+       return(((randx = randx*1103515245 + 12345)>>16) & 077777);
+}
diff --git a/usr/src/libc/gen/setjmp.s b/usr/src/libc/gen/setjmp.s
new file mode 100644 (file)
index 0000000..00dabcd
--- /dev/null
@@ -0,0 +1,42 @@
+/ C library -- setjmp, longjmp
+
+/      longjmp(a,v)
+/ will generate a "return(v)" from
+/ the last call to
+/      setjmp(a)
+/ by restoring sp, r5, pc from `a'
+/ and doing a return.
+/
+
+.globl _setjmp
+.globl _longjmp
+.globl csv, cret
+
+_setjmp:
+       mov     2(sp),r0
+       mov     r5,(r0)+
+       mov     sp,(r0)+
+       mov     (sp),(r0)
+       clr     r0
+       rts     pc
+
+_longjmp:
+       jsr     r5,csv
+       mov     4(r5),r1
+       mov     6(r5),r0
+       bne     1f
+       mov     $1,r0
+1:
+       cmp     (r5),(r1)
+       beq     1f
+       mov     (r5),r5
+       bne     1b
+/ panic -- r2-r4 lost
+       mov     (r1)+,r5
+       mov     (r1)+,sp
+       mov     (r1),(sp)
+       rts     pc
+1:
+       mov     4(r1),2(r5)
+       jmp     cret
+
diff --git a/usr/src/libc/gen/sleep.c b/usr/src/libc/gen/sleep.c
new file mode 100644 (file)
index 0000000..4226dc5
--- /dev/null
@@ -0,0 +1,40 @@
+#include <signal.h>
+#include <setjmp.h>
+
+static jmp_buf jmp;
+
+sleep(n)
+unsigned n;
+{
+       int sleepx();
+       unsigned altime;
+       int (*alsig)() = SIG_DFL;
+
+       if (n==0)
+               return;
+       altime = alarm(1000);   /* time to maneuver */
+       if (setjmp(jmp)) {
+               signal(SIGALRM, alsig);
+               alarm(altime);
+               return;
+       }
+       if (altime) {
+               if (altime > n)
+                       altime -= n;
+               else {
+                       n = altime;
+                       altime = 1;
+               }
+       }
+       alsig = signal(SIGALRM, sleepx);
+       alarm(n);
+       for(;;)
+               pause();
+       /*NOTREACHED*/
+}
+
+static
+sleepx()
+{
+       longjmp(jmp, 1);
+}
diff --git a/usr/src/libc/gen/stty.c b/usr/src/libc/gen/stty.c
new file mode 100644 (file)
index 0000000..1712124
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Writearound to old stty and gtty system calls
+ */
+
+#include <sgtty.h>
+
+stty(fd, ap)
+struct sgtty *ap;
+{
+       return(ioctl(fd, TIOCSETP, ap));
+}
+
+gtty(fd, ap)
+struct sgtty *ap;
+{
+       return(ioctl(fd, TIOCGETP, ap));
+}
diff --git a/usr/src/libc/gen/timezone.c b/usr/src/libc/gen/timezone.c
new file mode 100644 (file)
index 0000000..c80ddd8
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * The arguments are the number of minutes of time
+ * you are westward from Greenwich and whether DST is in effect.
+ * It returns a string
+ * giving the name of the local timezone.
+ *
+ * Sorry, I don't know all the names.
+ */
+
+static struct zone {
+       int     offset;
+       char    *stdzone;
+       char    *dlzone;
+} zonetab[] = {
+       4*60, "AST", "ADT",             /* Atlantic */
+       5*60, "EST", "EDT",             /* Eastern */
+       6*60, "CST", "CDT",             /* Central */
+       7*60, "MST", "MDT",             /* Mountain */
+       8*60, "PST", "PDT",             /* Pacific */
+       0, "GMT", 0,                    /* Greenwich */
+       -1
+};
+
+char *timezone(zone, dst)
+{
+       register struct zone *zp;
+       static char czone[10];
+       char *sign;
+
+       for (zp=zonetab; zp->offset!=-1; zp++)
+               if (zp->offset==zone) {
+                       if (dst && zp->dlzone)
+                               return(zp->dlzone);
+                       if (!dst && zp->stdzone)
+                               return(zp->stdzone);
+               }
+       if (zone<0) {
+               zone = -zone;
+               sign = "+";
+       } else
+               sign = "-";
+       sprintf(czone, "GMT%s%d:%02d", sign, zone/60, zone%60);
+       return(czone);
+}
diff --git a/usr/src/libc/gen/ttyname.c b/usr/src/libc/gen/ttyname.c
new file mode 100644 (file)
index 0000000..c7724e0
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * ttyname(f): return "/dev/ttyXX" which the the name of the
+ * tty belonging to file f.
+ *  NULL if it is not a tty
+ */
+
+#define        NULL    0
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+
+static char    dev[]   = "/dev/";
+char   *strcpy();
+char   *strcat();
+
+char *
+ttyname(f)
+{
+       struct stat fsb;
+       struct stat tsb;
+       struct direct db;
+       static char rbuf[32];
+       register df;
+
+       if (isatty(f)==0)
+               return(NULL);
+       if (fstat(f, &fsb) < 0)
+               return(NULL);
+       if ((fsb.st_mode&S_IFMT) != S_IFCHR)
+               return(NULL);
+       if ((df = open(dev, 0)) < 0)
+               return(NULL);
+       while (read(df, (char *)&db, sizeof(db)) == sizeof(db)) {
+               if (db.d_ino == 0)
+                       continue;
+               if (db.d_ino != fsb.st_ino)
+                       continue;
+               strcpy(rbuf, dev);
+               strcat(rbuf, db.d_name);
+               if (stat(rbuf, &tsb) < 0)
+                       continue;
+               if (tsb.st_dev==fsb.st_dev && tsb.st_ino==fsb.st_ino) {
+                       close(df);
+                       return(rbuf);
+               }
+       }
+       close(df);
+       return(NULL);
+}
diff --git a/usr/src/libc/gen/ttyslot.c b/usr/src/libc/gen/ttyslot.c
new file mode 100644 (file)
index 0000000..6449aab
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Return the number of the slot in the utmp file
+ * corresponding to the current user: try for file 0, 1, 2.
+ * Definition is the line number in the /etc/ttys file.
+ */
+
+
+char   *ttyname();
+char   *getttys();
+char   *rindex();
+static char    ttys[]  = "/etc/ttys";
+
+#define        NULL    0
+
+ttyslot()
+{
+       register char *tp, *p;
+       register s, tf;
+
+       if ((tp=ttyname(0))==NULL && (tp=ttyname(1))==NULL && (tp=ttyname(2))==NULL)
+               return(0);
+       if ((p = rindex(tp, '/')) == NULL)
+               p = tp;
+       else
+               p++;
+       if ((tf=open(ttys, 0)) < 0)
+               return(0);
+       s = 0;
+       while (tp = getttys(tf)) {
+               s++;
+               if (strcmp(p, tp)==0) {
+                       close(tf);
+                       return(s);
+               }
+       }
+       close(tf);
+       return(0);
+}
+
+static char *
+getttys(f)
+{
+       static char line[32];
+       register char *lp;
+
+       lp = line;
+       for (;;) {
+               if (read(f, lp, 1) != 1)
+                       return(NULL);
+               if (*lp =='\n') {
+                       *lp = '\0';
+                       return(line+2);
+               }
+               if (lp >= &line[32])
+                       return(line+2);
+               lp++;
+       }
+}