BSD 4 development
authorJim Kulp <jekulp@mit-mc.arpa>
Sun, 19 Oct 1980 09:55:59 +0000 (01:55 -0800)
committerJim Kulp <jekulp@mit-mc.arpa>
Sun, 19 Oct 1980 09:55:59 +0000 (01:55 -0800)
Work on file usr/src/lib/libjobs/signal.s
Work on file usr/src/lib/libjobs/killpg.s
Work on file usr/src/lib/libjobs/makefile
Work on file usr/src/lib/libjobs/setpgrp.s
Work on file usr/src/lib/libjobs/sigset.c
Work on file usr/src/lib/libjobs/wait3.s
Work on file usr/src/lib/libjobs/getwd.c

Synthesized-from: CSRG//cd1/4.0

usr/src/lib/libjobs/getwd.c [new file with mode: 0644]
usr/src/lib/libjobs/killpg.s [new file with mode: 0644]
usr/src/lib/libjobs/makefile [new file with mode: 0644]
usr/src/lib/libjobs/setpgrp.s [new file with mode: 0644]
usr/src/lib/libjobs/signal.s [new file with mode: 0644]
usr/src/lib/libjobs/sigset.c [new file with mode: 0644]
usr/src/lib/libjobs/wait3.s [new file with mode: 0644]

diff --git a/usr/src/lib/libjobs/getwd.c b/usr/src/lib/libjobs/getwd.c
new file mode 100644 (file)
index 0000000..5f9a067
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Getwd
+ */
+#include       <sys/param.h>
+#include       <sys/stat.h>
+#include       <sys/dir.h>
+
+#define        dot     "."
+#define        dotdot  ".."
+
+static char    *name;
+
+static int     file;
+static int     off     = -1;
+static struct  stat    d, dd;
+static struct  direct  dir;
+
+char *
+getwd(np)
+char *np;
+{
+       int rdev, rino;
+
+       *np++ = '/';
+       name = np;
+       stat("/", &d);
+       rdev = d.st_dev;
+       rino = d.st_ino;
+       for (;;) {
+               stat(dot, &d);
+               if (d.st_ino==rino && d.st_dev==rdev)
+                       goto done;
+               if ((file = open(dotdot,0)) < 0)
+                       prexit("getwd: cannot open ..\n");
+               fstat(file, &dd);
+               chdir(dotdot);
+               if(d.st_dev == dd.st_dev) {
+                       if(d.st_ino == dd.st_ino)
+                               goto done;
+                       do
+                               if (read(file, (char *)&dir, sizeof(dir)) < sizeof(dir))
+                                       prexit("getwd: read error in ..\n");
+                       while (dir.d_ino != d.st_ino);
+               }
+               else do {
+                               if(read(file, (char *)&dir, sizeof(dir)) < sizeof(dir))
+                                       prexit("getwd: read error in ..\n");
+                               stat(dir.d_name, &dd);
+                       } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
+               close(file);
+               cat();
+       }
+done:
+       name--;
+       if (chdir(name) < 0)
+               prexit("getwd: can't change back\n");
+       return (name);
+}
+
+cat()
+{
+       register i, j;
+
+       i = -1;
+       while (dir.d_name[++i] != 0);
+       if ((off+i+2) > 1024-1)
+               return;
+       for(j=off+1; j>=0; --j)
+               name[j+i+1] = name[j];
+       if (off >= 0)
+               name[i] = '/';
+       off=i+off+1;
+       name[off] = 0;
+       for(--i; i>=0; --i)
+               name[i] = dir.d_name[i];
+}
+
+prexit(cp)
+char *cp;
+{
+       write(2, cp, strlen(cp));
+       exit(1);
+}
diff --git a/usr/src/lib/libjobs/killpg.s b/usr/src/lib/libjobs/killpg.s
new file mode 100644 (file)
index 0000000..002511b
--- /dev/null
@@ -0,0 +1,15 @@
+# C library -- killpg
+
+       .set    kill,37
+.globl _killpg
+.globl cerror
+
+_killpg:
+       .word   0x0000
+       mnegl   8(ap),8(ap)             # kill with - signo is killpg
+       chmk    $kill
+       bcc     noerror
+       jmp     cerror
+noerror:
+       clrl    r0
+       ret
diff --git a/usr/src/lib/libjobs/makefile b/usr/src/lib/libjobs/makefile
new file mode 100644 (file)
index 0000000..5df29b2
--- /dev/null
@@ -0,0 +1,14 @@
+CFLAGS=-O
+OBJS=  getwd.o killpg.o setpgrp.o signal.o sigset.o wait3.o
+
+libjobs.a: ${OBJS}
+       ar cr libjobs.a `lorder ${OBJS}`
+
+install:
+       install -c libjobs.a $(DESTDIR)/usr/lib
+       ranlib $(DESTDIR)/usr/lib/libjobs.a
+       -rm $(DESTDIR)/usr/lib/libnew.a
+       ln $(DESTDIR)/usr/lib/libjobs.a $(DESTDIR)/usr/lib/libnew.a
+
+clean:
+       rm libjobs.a *.o
diff --git a/usr/src/lib/libjobs/setpgrp.s b/usr/src/lib/libjobs/setpgrp.s
new file mode 100644 (file)
index 0000000..9f62ffc
--- /dev/null
@@ -0,0 +1,34 @@
+# C library -- setpgrp, getpgrp
+
+# setpgrp(pid, pgrp);  /* set pgrp of pid and descendants to pgrp */
+# if pid==0 use current pid
+#
+# getpgrp(pid)
+# implemented as setpgrp(pid, -1)
+
+       .set    setpgrp,39
+.globl _setpgrp
+.globl _getpgrp
+.globl  cerror
+
+       .align  1
+_setpgrp:
+       .word   0x0000
+       chmk    $setpgrp
+       bcc     noerror
+       jmp     cerror
+noerror:
+       ret
+
+       .align  1
+_getpgrp:
+       .word   0x0000
+       pushl   $-1
+       pushl   4(ap)
+       calls   $2,gpgrp
+       ret
+gpgrp:
+       .word   0x0000
+       chmk    $setpgrp
+       bcc     noerror
+       jmp     cerror
diff --git a/usr/src/lib/libjobs/signal.s b/usr/src/lib/libjobs/signal.s
new file mode 100644 (file)
index 0000000..ac59eaf
--- /dev/null
@@ -0,0 +1,66 @@
+# C library -- sigsys
+
+# sigsys(n, SIG_DFL);          /* default action on signal(n) */
+# sigsys(n, SIG_HOLD);         /* block signal temporarily */
+# sigsys(n, SIG_IGN);          /* ignore signal(n) */
+# sigsys(n, label);            /* goto label on signal(n) */
+# sigsys(n, DEFERSIG(label));  /* goto label with signal SIG_HOLD */
+
+# returns old label, only one level.
+
+       .set    SIGDORTI,0x200
+
+       .set    signal,48
+.globl _sigsys
+.globl  cerror
+
+       .align  1
+_sigsys:
+       .word   0x0000
+       chmk    $signal
+       bcc     noerror
+       jmp     cerror
+noerror:
+       ret
+
+#
+# sigpeel(n, newact)
+#
+# when called from routine which was called by system, peels
+# back frames to the last one, then calls the system to reenable
+# the signal with newact, arranging to clean the stack before the
+# signal can happen again
+#
+.globl _sigpeel
+       .align  1
+_sigpeel:
+       .word   0x0000
+       .set    RETOFF,16       # offset of return address in frame
+# get signal number value to set
+       movl    4(ap),r0
+       movl    8(ap),r1
+       movab   unw1,RETOFF(fp)
+       ret                     # peel off our frame
+# top frame is now frame of routine signal action called
+unw1:
+       movab   unw2,RETOFF(fp)
+       ret
+# now frame from callg of ``locore.s/sigcode()'' is gone
+# if no value to set, can just ret now to go back to old code
+# with an ret->rei, else must make the frame passed to us into a
+# signal call frame by putting the new signal code in the
+# second word, and call the kernel which will pop off the frame.
+unw2:
+       tstl    r1
+       bneq    unw3
+       ret                     # easy
+# mark dorti wanted, and reenable signal
+unw3:
+       bisl3   $SIGDORTI,r0,4(ap)
+###    movl    r0,4(ap)        ### for testing on old system
+       movl    r1,8(ap)
+       chmk    $signal
+       halt                    # can't happen
+
+### for testing on old system
+###    ret                     # and then rei, natch
diff --git a/usr/src/lib/libjobs/sigset.c b/usr/src/lib/libjobs/sigset.c
new file mode 100644 (file)
index 0000000..15faefa
--- /dev/null
@@ -0,0 +1,185 @@
+#include <signal.h>
+#include <errno.h>
+/*
+ * signal system call interface package.
+ */
+extern errno;
+
+#ifdef PDP11
+#define BYTESPERVEC    4               /* size of machine language vector */
+extern char    mvectors[NSIG+1][BYTESPERVEC];
+#endif
+
+static int (*cactions[NSIG+1])();      /* saved callers signal actions */
+static char setflg[NSIG+1];            /* =1 means action perm ``sigset'' */
+int    (*sigsys())();
+int    _sigcatch();
+
+/*
+ * old signal protocol.  when signal occurs, further
+ * instances of same signal are not blocked, so that
+ * recursive signals are possible.  the action will
+ * not be re-enabled by these routines when return
+ * is made from the interrupt (compare sigset).
+ */
+int (*
+signal(signum, action))()
+register int signum;
+register int (*action)();
+{
+       register int (*retval)();
+
+       if (signum <= 0 || signum > NSIG) {
+               errno = EINVAL;
+               return (BADSIG);
+       }
+       retval = cactions[signum];
+       cactions[signum] = action;
+       if (action != SIG_IGN && action != SIG_DFL && action != SIG_HOLD)
+               if (SIGISDEFER(action))
+#ifdef PDP11
+                       action = DEFERSIG(mvectors[signum]);
+               else
+                       action = (int (*)())(int)mvectors[signum];
+#else
+                       action = DEFERSIG(_sigcatch);
+               else
+                       action = _sigcatch;
+#endif
+       action = sigsys(signum, action);
+       if (action == SIG_IGN || action == SIG_DFL || action == SIG_HOLD)
+               retval = action;
+       setflg[signum] = 0;     /* 'tis fleeting (madness may take its toll) */
+       return (retval);
+}
+
+/*
+ * set ``permanent'' action for this signal.  if a function,
+ * it will be deferred when interupt occurs and enabled again
+ * when return occurs.  after sigset, sighold and sigrelse can
+ * be used to protect signum signal critical sections.
+ */
+int (*
+sigset(signum, action))()
+register int signum;
+register int (*action)();
+{
+       register int (*retval)();
+
+       if (signum <= 0 || signum > NSIG) {
+               errno = EINVAL;
+               return (BADSIG);
+       }
+       retval = cactions[signum];
+       cactions[signum] = action;
+       if (action != SIG_IGN && action != SIG_DFL && action != SIG_HOLD)
+               action = DEFERSIG(_sigcatch);
+       action = sigsys(signum, action);
+       if (action == SIG_IGN || action == SIG_DFL || action == SIG_HOLD)
+               retval = action;
+       setflg[signum] = 1;             /* don't want to lose control! */
+       return (retval);
+}
+
+/*
+ * temporarily hold a signal until further notice
+ * via sigpause or sigrelse
+ */
+sighold(signum)
+register int signum;
+{
+
+       if (signum <= 0 || signum > NSIG) {
+               errno = EINVAL;
+               return;
+       }
+       sigsys(signum, SIG_HOLD);
+}
+
+/*
+ * atomically release the signal and pause
+ * if no signals pending.  signal will normally
+ * be held on return (unless an routine called at
+ * interrupt time resets it).
+ */
+sigpause(signum)
+register signum;
+{
+
+       if (signum <= 0 || signum > NSIG || setflg[signum] == 0) {
+               errno = EINVAL;
+               return;
+       }
+#ifdef PDP11
+       sigsys(signum|SIGDOPAUSE, DEFERSIG(mvectors[signum]));
+#else
+       sigsys(signum|SIGDOPAUSE, DEFERSIG(_sigcatch));
+#endif
+}
+
+/*
+ * re-enable signals after sighold or possibly after sigpause
+ */
+sigrelse(signum)
+register signum;
+{
+       if (signum <= 0 || signum > NSIG || setflg[signum] == 0) {
+               errno = EINVAL;
+               return (-1);
+       }
+#ifdef PDP11
+       sigsys(signum, DEFERSIG(mvectors[signum]));
+#else
+       sigsys(signum, DEFERSIG(_sigcatch));
+#endif
+       return (0);
+}
+
+/*
+ * ignore signal
+ */
+sigignore(signum)
+int signum;
+{
+
+       sigsys(signum, SIG_IGN);
+}
+
+#ifdef PDP11
+/*
+ * called at interrupt time.  on pdp11 assembly language
+ * routine resets signal catch to returned action, if
+ * returned action is not SIG_DFL.
+ */
+int (*
+_sigcatch(signum))()
+register signum;
+{
+
+       (*cactions[signum])(signum);            /* call the C routine */
+       if (setflg[signum])
+               return (DEFERSIG(mvectors[signum]);
+       else
+               return (SIG_DFL);               /* old protocol */
+}
+#else
+/*
+ * called at interrupt time.  on vax, sigpeel will peel
+ * off the interrupt frames and reenable the signal with
+ * the argument action (cleanly).  if the action is
+ * SIG_DFL sigpeel will do nothing, but we can as well
+ * return ourselves without its help.
+ */
+_sigcatch(signum, code)
+register signum;
+int code;
+{
+
+       (*cactions[signum])(signum);
+       if (setflg[signum]) {
+               sigpeel(signum, DEFERSIG(_sigcatch));
+               /*NOTREACHED*/
+       }
+       /* old protocol, just return */
+}
+#endif
diff --git a/usr/src/lib/libjobs/wait3.s b/usr/src/lib/libjobs/wait3.s
new file mode 100644 (file)
index 0000000..5505fd7
--- /dev/null
@@ -0,0 +1,30 @@
+# C library -- wait3
+
+# pid = wait3(&status, flags, &vmstat);
+#
+# pid == -1 if error
+# status indicates fate of process, if given
+# flags may indicate process is not to hang or
+# that untraced stopped children are to be reported.
+# vmstat optionally returns detailed resource usage information
+#
+
+       .set    wait3,7         # same as wait!
+.globl _wait3
+.globl  cerror
+
+       .align  1
+_wait3:
+       .word   0x0000
+       movl    8(ap),r0        # make it easy for system to get
+       movl    12(ap),r1       # these extra arguments
+       bispsw  $0xf            # flags wait3()
+       chmk    $wait3
+       bcc     noerror
+       jmp     cerror
+noerror:
+       tstl    4(ap)           # status desired?
+       beql    nostatus        # no
+       movl    r1,*4(ap)       # store child's status
+nostatus:
+       ret