aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/gen
diff options
context:
space:
mode:
authorsvn2git <svn2git@FreeBSD.org>1994-05-01 08:00:00 +0000
committersvn2git <svn2git@FreeBSD.org>1994-05-01 08:00:00 +0000
commita16f65c7d117419bd266c28a1901ef129a337569 (patch)
tree2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /lib/libc/gen
parent8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff)
Diffstat (limited to 'lib/libc/gen')
-rw-r--r--lib/libc/gen/Makefile.inc43
-rw-r--r--lib/libc/gen/alarm.34
-rw-r--r--lib/libc/gen/crypt.c2
-rw-r--r--lib/libc/gen/ctype_.c9
-rw-r--r--lib/libc/gen/directory.32
-rw-r--r--lib/libc/gen/err.311
-rw-r--r--lib/libc/gen/fnmatch.325
-rw-r--r--lib/libc/gen/fnmatch.c85
-rw-r--r--lib/libc/gen/getcap.35
-rw-r--r--lib/libc/gen/getgrent.32
-rw-r--r--lib/libc/gen/getgrent.c87
-rw-r--r--lib/libc/gen/getpwent.c288
-rw-r--r--lib/libc/gen/isctype.c15
-rw-r--r--lib/libc/gen/isupper.32
-rw-r--r--lib/libc/gen/ldexp.32
-rw-r--r--lib/libc/gen/msgctl.c15
-rw-r--r--lib/libc/gen/msgget.c14
-rw-r--r--lib/libc/gen/msgrcv.c17
-rw-r--r--lib/libc/gen/msgsnd.c16
-rw-r--r--lib/libc/gen/nlist.32
-rw-r--r--lib/libc/gen/regexp.3315
-rw-r--r--lib/libc/gen/regexp/COPYRIGHT22
-rw-r--r--lib/libc/gen/regexp/README84
-rw-r--r--lib/libc/gen/regexp/regerror.c18
-rw-r--r--lib/libc/gen/regexp/regexp.3315
-rw-r--r--lib/libc/gen/regexp/regexp.c1320
-rw-r--r--lib/libc/gen/regexp/regexp.h21
-rw-r--r--lib/libc/gen/regexp/regmagic.h5
-rw-r--r--lib/libc/gen/regexp/regsub.c81
-rw-r--r--lib/libc/gen/semconfig.c13
-rw-r--r--lib/libc/gen/semctl.c15
-rw-r--r--lib/libc/gen/semget.c15
-rw-r--r--lib/libc/gen/semop.c15
-rw-r--r--lib/libc/gen/setmode.c8
-rw-r--r--lib/libc/gen/signal.34
-rw-r--r--lib/libc/gen/tcgetpgrp.379
-rw-r--r--lib/libc/gen/tcsetattr.3330
-rw-r--r--lib/libc/gen/tcsetpgrp.3100
-rw-r--r--lib/libc/gen/timezone.32
-rw-r--r--lib/libc/gen/timezone.c1
-rw-r--r--lib/libc/gen/ualarm.32
41 files changed, 1119 insertions, 2292 deletions
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index f7d472e667e4..0f0a66405d13 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -1,23 +1,22 @@
# @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
# gen sources
-.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen ${.CURDIR}/gen/regexp
+.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen
SRCS+= alarm.c assert.c clock.c crypt.c ctermid.c ctime.c ctype_.c \
directory.c difftime.c disklabel.c err.c errlst.c exec.c \
fnmatch.c frexp.c fstab.c fts.c getcap.c getcwd.c getgrent.c \
getlogin.c getmntinfo.c getpass.c getpwent.c getsubopt.c getttyent.c \
getusershell.c glob.c infinity.c initgroups.c insque.c isatty.c \
- isctype.c isinf.c mktemp.c nice.c nlist.c pause.c popen.c psignal.c \
- raise.c setjmperr.c setmode.c setrgid.c setruid.c \
+ isctype.c isinf.c mktemp.c msgctl.c msgget.c msgsnd.c msgrcv.c \
+ nice.c nlist.c pause.c popen.c psignal.c raise.c scandir.c \
+ semconfig.c semctl.c semget.c semop.c \
+ setjmperr.c setmode.c setrgid.c setruid.c \
shmat.c shmctl.c shmdt.c shmget.c \
- siginterrupt.c \
- scandir.c siglist.c signal.c sigsetops.c sleep.c syslog.c termios.c \
- time.c times.c timezone.c ttyname.c ttyslot.c ualarm.c unvis.c \
- usleep.c utime.c valloc.c vis.c wait.c wait3.c waitpid.c
-
-# gen/regexp sources
-SRCS+= regerror.c regexp.c regsub.c
+ siginterrupt.c siglist.c signal.c sigsetops.c sleep.c syslog.c \
+ termios.c time.c times.c timezone.c ttyname.c ttyslot.c \
+ ualarm.c unvis.c usleep.c utime.c valloc.c vis.c \
+ wait.c wait3.c waitpid.c
.if (${MACHINE} == "hp300")
SRCS+= _setjmp.s alloca.s fabs.s ldexp.s modf.s setjmp.s
@@ -27,8 +26,8 @@ SRCS+= adddf3.s addsf3.s ashlsi3.s ashrsi3.s cmpdf2.s cmpsf2.s divdf3.s \
negdf2.s negsf2.s saveregs.c subdf3.s subsf3.s truncdfsf2.s udivsi3.s \
umodsi3.s umulsi3.s
.elif (${MACHINE} == "i386")
-SRCS+= _setjmp.s alloca.s fabs.s ldexp.c modf.s setjmp.s sigsetjmp.s
-SRCS+= divsi3.s fixdfsi.s fixunsdfsi.s udivsi3.s
+SRCS+= _setjmp.S alloca.S fabs.S ldexp.c modf.S setjmp.S sigsetjmp.S
+SRCS+= divsi3.S fixdfsi.S fixunsdfsi.S udivsi3.S
.elif (${MACHINE} == "tahoe")
CFLAGS+=-I/sys
SRCS+= _setjmp.s alloca.s fabs.s ldexp.s modf.s setjmp.s
@@ -48,14 +47,14 @@ MAN3+= gen/alarm.3 gen/clock.3 gen/crypt.3 gen/ctermid.3 gen/ctime.3 \
gen/islower.3 gen/isprint.3 gen/ispunct.3 gen/isspace.3 \
gen/isupper.3 gen/isxdigit.3 gen/ldexp.3 gen/modf.3 gen/nice.3 \
gen/nlist.3 gen/pause.3 gen/popen.3 gen/psignal.3 gen/raise.3 \
- gen/regexp.3 gen/scandir.3 gen/setjmp.3 gen/setmode.3 gen/setuid.3 \
+ gen/scandir.3 gen/setjmp.3 gen/setmode.3 gen/setuid.3 \
gen/siginterrupt.3 gen/signal.3 gen/sigsetops.3 gen/sleep.3 \
- gen/syslog.3 gen/tcsendbreak.3 gen/time.3 gen/times.3 \
- gen/timezone.3 gen/tolower.3 gen/toupper.3 gen/ttyname.3 \
- gen/tzset.3 gen/ualarm.3 gen/unvis.3 gen/usleep.3 gen/utime.3 \
- gen/valloc.3 gen/vis.3
+ gen/syslog.3 gen/tcgetpgrp.3 gen/tcsendbreak.3 gen/tcsetattr.3 \
+ gen/tcsetpgrp.3 gen/time.3 gen/times.3 gen/timezone.3 gen/tolower.3 \
+ gen/toupper.3 gen/ttyname.3 gen/tzset.3 gen/ualarm.3 gen/unvis.3 \
+ gen/usleep.3 gen/utime.3 gen/valloc.3 gen/vis.3
-MLINKS= crypt.3 encrypt.3 crypt.3 setkey.3
+MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3
MLINKS+=ctime.3 asctime.3 ctime.3 difftime.3 ctime.3 gmtime.3 \
ctime.3 localtime.3 ctime.3 mktime.3
MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \
@@ -83,8 +82,6 @@ MLINKS+=insque.3 remque.3
MLINKS+=isinf.3 isnan.3
MLINKS+=popen.3 pclose.3
MLINKS+=psignal.3 sys_siglist.3
-MLINKS+=regexp.3 regcomp.3 regexp.3 regexec.3 regexp.3 regsub.3 \
- regexp.3 regerror.3
MLINKS+=scandir.3 alphasort.3
MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \
setjmp.3 sigsetjmp.3 setjmp.3 siglongjmp.3 setjmp.3 longjmperror.3
@@ -97,8 +94,10 @@ MLINKS+=sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \
MLINKS+=syslog.3 closelog.3 syslog.3 openlog.3 syslog.3 setlogmask.3 \
syslog.3 vsyslog.3
MLINKS+=tcsendbreak.3 tcdrain.3 tcsendbreak.3 tcflush.3 tcsendbreak.3 tcflow.3
-
-
+MLINKS+=tcsetattr.3 cfgetispeed.3 tcsetattr.3 cfsetispeed.3 \
+ tcsetattr.3 cfgetospeed.3 tcsetattr.3 cfsetospeed.3 \
+ tcsetattr.3 cfsetspeed.3 tcsetattr.3 cfmakeraw.3 \
+ tcsetattr.3 tcgetattr.3
MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyslot.3
MLINKS+=tzset.3 tzsetwall.3
diff --git a/lib/libc/gen/alarm.3 b/lib/libc/gen/alarm.3
index c34abc21e6af..63c338ebac1c 100644
--- a/lib/libc/gen/alarm.3
+++ b/lib/libc/gen/alarm.3
@@ -56,7 +56,7 @@ before asserting the terminating signal
When the signal has successfully been caught,
.Fn alarm
returns the amount of time left on the clock.
-The maximum mumber of
+The maximum number of
.Ar seconds
allowed
is 2147483647.
@@ -65,7 +65,7 @@ If an alarm has been set with
.Fn alarm ,
another call to
.Fn alarm
-will superceed the prior call.
+will supercede the prior call.
The request
.Fn alarm "0"
voids the current
diff --git a/lib/libc/gen/crypt.c b/lib/libc/gen/crypt.c
index be5d6873fe48..e0a96988ac01 100644
--- a/lib/libc/gen/crypt.c
+++ b/lib/libc/gen/crypt.c
@@ -36,7 +36,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/* from static char sccsid[] = "@(#)crypt.c 5.11 (Berkeley) 6/25/91"; */
-static char rcsid[] = "$Header: /a/cvs/386BSD/src/lib/libc/gen/crypt.c,v 1.6 1993/08/29 22:03:56 nate Exp $";
+static char rcsid[] = "$Header: /home/cvs/386BSD/src/lib/libc/gen/crypt.c,v 1.6 1993/08/29 22:03:56 nate Exp $";
#endif /* LIBC_SCCS and not lint */
#include <unistd.h>
diff --git a/lib/libc/gen/ctype_.c b/lib/libc/gen/ctype_.c
index b6f83051411e..d361c1617cea 100644
--- a/lib/libc/gen/ctype_.c
+++ b/lib/libc/gen/ctype_.c
@@ -1,4 +1,13 @@
/*
+ * Copyright (c) UNIX System Laboratories, Inc. All or some portions
+ * of this file are derived from material licensed to the
+ * University of California by American Telephone and Telegraph Co.
+ * or UNIX System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * $Id: ctype_.c,v 1.1.1.1.2.1 1994/05/04 07:39:42 rgrimes Exp $
+ */
+/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3
index cae5ea3dda56..6b5ea9d88301 100644
--- a/lib/libc/gen/directory.3
+++ b/lib/libc/gen/directory.3
@@ -48,7 +48,7 @@
.Fd #include <dirent.h>
.Ft DIR *
.Fn opendir "const char *filename"
-.Ft struct direct
+.Ft struct dirent *
.Fn readdir "DIR *dirp"
.Ft long
.Fn telldir "const DIR *dirp"
diff --git a/lib/libc/gen/err.3 b/lib/libc/gen/err.3
index 44ca0942c1b3..2a3f4c391fd3 100644
--- a/lib/libc/gen/err.3
+++ b/lib/libc/gen/err.3
@@ -1,5 +1,5 @@
-.\" Copyright (c) 1993 The Regents of the University of California.
-.\" All rights reserved.
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)err.3 5.2 (Berkeley) 3/19/93
+.\" @(#)err.3 8.1 (Berkeley) 6/9/93
.\"
-.Dd "March 19, 1993"
+.Dd "June 9, 1993"
.Dt ERR 3
.Os BSD 4
.Sh NAME
@@ -125,5 +125,4 @@ The
.Fn err
and
.Fn warn
-functions are
-.Ud .
+functions first appeared in 4.4BSD.
diff --git a/lib/libc/gen/fnmatch.3 b/lib/libc/gen/fnmatch.3
index 2d967d2d1bd0..d3d3ccaa3b6e 100644
--- a/lib/libc/gen/fnmatch.3
+++ b/lib/libc/gen/fnmatch.3
@@ -1,5 +1,5 @@
-.\" Copyright (c) 1989, 1991 The Regents of the University of California.
-.\" All rights reserved.
+.\" Copyright (c) 1989, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Guido van Rossum.
@@ -31,9 +31,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)fnmatch.3 5.4 (Berkeley) 6/28/92
+.\" from: @(#)fnmatch.3 8.1 (Berkeley) 6/9/93
+.\" $Id: fnmatch.3,v 1.3 1993/11/23 00:10:08 jtc Exp $
.\"
-.Dd June 28, 1992
+.Dd June 9, 1993
.Dt FNMATCH 3
.Os
.Sh NAME
@@ -94,7 +95,6 @@ Additionally, if
.Dv FNM_PATHNAME
is set,
a period is ``leading'' if it immediately follows a slash.
-.Em "This flag is not currently implemented."
.El
.Sh RETURN VALUES
The
@@ -110,19 +110,16 @@ otherwise, it returns the value
.Xr glob 3 ,
.Xr wordexp 3 ,
.Xr regexp 3
+.Sh STANDARDS
+The
+.Fn fnmatch
+function is expected to conform to
+.St -p1003.2-92 .
.Sh HISTORY
The
.Fn fnmatch
-function is
-.Ud .
+function first appeared in 4.4BSD.
.Sh BUGS
-Quotes and slashes in range patterns are not handled correctly by
-this implementation.
-.Pp
-The
-.Dv FNM_PERIOD
-flag is not implemented.
-.Pp
The pattern
.Ql *
matches the empty string, even if
diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c
index 7b54c3b7254a..9d64cf5573ad 100644
--- a/lib/libc/gen/fnmatch.c
+++ b/lib/libc/gen/fnmatch.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
@@ -35,11 +35,12 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)fnmatch.c 5.6 (Berkeley) 6/28/92";
+/* from: static char sccsid[] = "@(#)fnmatch.c 8.1 (Berkeley) 6/4/93"; */
+static char *rcsid = "$Id: fnmatch.c,v 1.3 1993/11/23 00:10:09 jtc Exp $";
#endif /* LIBC_SCCS and not lint */
/*
- * Function fnmatch() as proposed in POSIX 1003.2 B.6 (D11.2).
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
* Compares a filename or pathname to a pattern.
*/
@@ -48,12 +49,14 @@ static char sccsid[] = "@(#)fnmatch.c 5.6 (Berkeley) 6/28/92";
#define EOS '\0'
-static const char *rangematch __P((const char *, int));
+static const char *rangematch __P((const char *, int, int));
+int
fnmatch(pattern, string, flags)
register const char *pattern, *string;
int flags;
{
+ const char *stringstart = string;
register char c;
char test;
@@ -62,9 +65,14 @@ fnmatch(pattern, string, flags)
case EOS:
return (*string == EOS ? 0 : FNM_NOMATCH);
case '?':
- if ((test = *string++) == EOS ||
- test == '/' && flags & FNM_PATHNAME)
+ if (*string == EOS)
return (FNM_NOMATCH);
+ if (*string == '/' && (flags & FNM_PATHNAME))
+ return (FNM_NOMATCH);
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+ ++string;
break;
case '*':
c = *pattern;
@@ -72,6 +80,10 @@ fnmatch(pattern, string, flags)
while (c == '*')
c = *++pattern;
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ return (FNM_NOMATCH);
+
/* Optimize for pattern with * at end or before /. */
if (c == EOS)
if (flags & FNM_PATHNAME)
@@ -87,7 +99,7 @@ fnmatch(pattern, string, flags)
/* General case, use recursion. */
while ((test = *string) != EOS) {
- if (!fnmatch(pattern, string, flags))
+ if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
return (0);
if (test == '/' && flags & FNM_PATHNAME)
break;
@@ -95,11 +107,13 @@ fnmatch(pattern, string, flags)
}
return (FNM_NOMATCH);
case '[':
- if ((test = *string++) == EOS ||
- test == '/' && flags & FNM_PATHNAME)
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && flags & FNM_PATHNAME)
return (FNM_NOMATCH);
- if ((pattern = rangematch(pattern, test)) == NULL)
+ if ((pattern = rangematch(pattern, *string, flags)) == NULL)
return (FNM_NOMATCH);
+ ++string;
break;
case '\\':
if (!(flags & FNM_NOESCAPE)) {
@@ -107,9 +121,6 @@ fnmatch(pattern, string, flags)
c = '\\';
--pattern;
}
- if (c != *string++)
- return (FNM_NOMATCH);
- break;
}
/* FALLTHROUGH */
default:
@@ -121,30 +132,48 @@ fnmatch(pattern, string, flags)
}
static const char *
-rangematch(pattern, test)
+rangematch(pattern, test, flags)
register const char *pattern;
register int test;
+ int flags;
{
register char c, c2;
int negate, ok;
- if (negate = (*pattern == '!'))
- ++pattern;
-
- /*
- * XXX
- * TO DO: quoting
+ /* A bracket expression starting with an unquoted circumflex
+ * character produces unspecified results (IEEE 1003.2-1992,
+ * 3.13.2). I have chosen to treat it like '!', for
+ * consistancy with regular expression syntax.
*/
+ if (negate = (*pattern == '!' || *pattern == '^')) {
+ pattern++;
+ }
+
for (ok = 0; (c = *pattern++) != ']';) {
- if (c == EOS)
- return (NULL); /* Illegal pattern. */
- if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') {
- if (c <= test && test <= c2)
- ok = 1;
- pattern += 2;
+ if (c == '\\' && !(flags & FNM_NOESCAPE)) {
+ c = *pattern++;
+ }
+ if (c == EOS) {
+ return (NULL);
}
- else if (c == test)
+
+ if (*pattern == '-'
+ && (c2 = *(pattern+1)) != EOS && c2 != ']') {
+ pattern += 2;
+ if (c2 == '\\' && !(flags & FNM_NOESCAPE)) {
+ c2 = *pattern++;
+ }
+ if (c2 == EOS) {
+ return (NULL);
+ }
+
+ if (c <= test && test <= c2) {
+ ok = 1;
+ }
+ } else if (c == test) {
ok = 1;
+ }
}
+
return (ok == negate ? NULL : pattern);
}
diff --git a/lib/libc/gen/getcap.3 b/lib/libc/gen/getcap.3
index 4af162f1af62..d18b3797bc7e 100644
--- a/lib/libc/gen/getcap.3
+++ b/lib/libc/gen/getcap.3
@@ -32,7 +32,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)getcap.3 5.4 (Berkeley) 8/11/92
+.\" from: @(#)getcap.3 5.4 (Berkeley) 8/11/92
+.\" $Id: getcap.3,v 1.1.2.1 1994/05/01 16:05:00 jkh Exp $
.\"
.Dd "August 11, 1992"
.Dt GETCAP 3
@@ -236,7 +237,7 @@ Upon completion of the database 0 is returned, 1 is returned upon successful
return of record with possibly more remaining (we haven't reached the end of
the database yet), 2 is returned if the record contains an unresolved
.Nm tc
-expansion, \-1 is returned if an system error occured, and \-2
+expansion, \-1 is returned if an system error occurred, and \-2
is returned if a potential reference loop is detected (see
.Ic tc=
comments below).
diff --git a/lib/libc/gen/getgrent.3 b/lib/libc/gen/getgrent.3
index 45d3bced27ab..fd2e2e194e76 100644
--- a/lib/libc/gen/getgrent.3
+++ b/lib/libc/gen/getgrent.3
@@ -96,7 +96,7 @@ function
sequentially reads the group database and is intended for programs
that wish to step through the complete list of groups.
.Pp
-All three routines will open the group file for reading, if necesssary.
+All three routines will open the group file for reading, if necessary.
.Pp
The
.Fn setgroupent
diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c
index 60593c2831fd..18f7079eff30 100644
--- a/lib/libc/gen/getgrent.c
+++ b/lib/libc/gen/getgrent.c
@@ -32,13 +32,20 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getgrent.c 5.9 (Berkeley) 4/1/91";
+/* static char *sccsid = "from: @(#)getgrent.c 5.9 (Berkeley) 4/1/91"; */
+static char *rcsid = "$Id: getgrent.c,v 1.3 1994/01/11 19:00:57 nate Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <grp.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
static FILE *_gr_fp;
static struct group _gr_group;
@@ -50,6 +57,11 @@ static char *members[MAXGRP];
#define MAXLINELENGTH 1024
static char line[MAXLINELENGTH];
+#ifdef YP
+static char *__ypcurrent, *__ypdomain;
+static int __ypcurrentlen, __ypmode=0;
+#endif
+
struct group *
getgrent()
{
@@ -90,7 +102,7 @@ getgrgid(gid)
return(rval ? &_gr_group : NULL);
}
-static
+static int
start_gr()
{
if (_gr_fp) {
@@ -100,10 +112,10 @@ start_gr()
return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0);
}
-int
+void
setgrent()
{
- return(setgroupent(0));
+ (void) setgroupent(0);
}
int
@@ -125,27 +137,88 @@ endgrent()
}
}
-static
+static int
grscan(search, gid, name)
register int search, gid;
register char *name;
{
register char *cp, **m;
char *bp;
- char *fgets(), *strsep(), *index();
for (;;) {
+#ifdef YP
+ if(__ypmode) {
+ char *key, *data;
+ int keylen, datalen;
+ int r;
+
+ if(!__ypdomain) {
+ if(yp_get_default_domain(&__ypdomain)) {
+ __ypmode = 0;
+ continue;
+ }
+ }
+ if(__ypcurrent) {
+ r = yp_next(__ypdomain, "group.byname",
+ __ypcurrent, __ypcurrentlen,
+ &key, &keylen, &data, &datalen);
+ free(__ypcurrent);
+ /*printf("yp_next %d\n", r);*/
+ switch(r) {
+ case 0:
+ break;
+ default:
+ __ypcurrent = NULL;
+ __ypmode = 0;
+ free(data);
+ continue;
+ }
+ __ypcurrent = key;
+ __ypcurrentlen = keylen;
+ bcopy(data, line, datalen);
+ free(data);
+ } else {
+ r = yp_first(__ypdomain, "group.byname",
+ &__ypcurrent, &__ypcurrentlen,
+ &data, &datalen);
+ /*printf("yp_first %d\n", r);*/
+ switch(r) {
+ case 0:
+ break;
+ default:
+ __ypmode = 0;
+ free(data);
+ continue;
+ }
+ bcopy(data, line, datalen);
+ free(data);
+ }
+ line[datalen] = '\0';
+ /*printf("line = %s\n", line);*/
+ bp = line;
+ goto parse;
+ }
+#endif
if (!fgets(line, sizeof(line), _gr_fp))
return(0);
bp = line;
/* skip lines that are too big */
- if (!index(line, '\n')) {
+ if (!strchr(line, '\n')) {
int ch;
while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
;
continue;
}
+#ifdef YP
+ if ((strcmp("+\n", line) == 0) || (strncmp("+:*:0:", line, 5) == 0)) {
+ if(_yp_check(NULL)) {
+ __ypmode = 1;
+ continue;
+ }
+ }
+parse:
+#endif
_gr_group.gr_name = strsep(&bp, ":\n");
if (search && name && strcmp(_gr_group.gr_name, name))
continue;
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c
index fe1b19cc2563..93a09ee52ff6 100644
--- a/lib/libc/gen/getpwent.c
+++ b/lib/libc/gen/getpwent.c
@@ -32,7 +32,8 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getpwent.c 5.21 (Berkeley) 3/14/91";
+/*static char *sccsid = "from: @(#)getpwent.c 5.21 (Berkeley) 3/14/91";*/
+static char *rcsid = "$Id: getpwent.c,v 1.4 1994/01/11 19:00:58 nate Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -46,6 +47,12 @@ static char sccsid[] = "@(#)getpwent.c 5.21 (Berkeley) 3/14/91";
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#ifdef YP
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
static struct passwd _pw_passwd; /* password structure */
static DB *_pw_db; /* password database */
@@ -53,21 +60,142 @@ static int _pw_keynum; /* key counter */
static int _pw_stayopen; /* keep fd's open */
static int __hashpw(), __initdb();
+#ifdef YP
+static char *__ypcurrent, *__ypdomain;
+static int __ypcurrentlen, __ypmode=0;
+static char line[1024];
+
+static int
+__ypparse(pw, s)
+struct passwd *pw;
+char *s;
+{
+ char *bp, *cp;
+
+ bp = s;
+ pw->pw_name = strsep(&bp, ":\n");
+ pw->pw_passwd = strsep(&bp, ":\n");
+ if (!(cp = strsep(&bp, ":\n")))
+ return 1;
+ pw->pw_uid = atoi(cp);
+ if (!(cp = strsep(&bp, ":\n")))
+ return 0;
+ pw->pw_gid = atoi(cp);
+ pw->pw_change = 0;
+ pw->pw_class = "";
+ pw->pw_gecos = strsep(&bp, ":\n");
+ pw->pw_dir = strsep(&bp, ":\n");
+ pw->pw_shell = strsep(&bp, ":\n");
+ pw->pw_expire = 0;
+ return 0;
+}
+#endif
+
struct passwd *
getpwent()
{
DBT key;
char bf[sizeof(_pw_keynum) + 1];
+#ifdef YP
+ char *bp, *cp;
+#endif
if (!_pw_db && !__initdb())
return((struct passwd *)NULL);
+#ifdef YP
+again:
+ if(__ypmode) {
+ char *key, *data;
+ int keylen, datalen;
+ int r;
+
+ if(!__ypdomain) {
+ if( _yp_check(&__ypdomain) == 0) {
+ __ypmode = 0;
+ goto again;
+ }
+ }
+ if(__ypcurrent) {
+ r = yp_next(__ypdomain, "passwd.byname",
+ __ypcurrent, __ypcurrentlen,
+ &key, &keylen, &data, &datalen);
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ /*printf("yp_next %d\n", r);*/
+ switch(r) {
+ case 0:
+ break;
+ default:
+ __ypcurrent = NULL;
+ __ypmode = 0;
+ free(data);
+ data = NULL;
+ goto again;
+ }
+ __ypcurrent = key;
+ __ypcurrentlen = keylen;
+ bcopy(data, line, datalen);
+ free(data);
+ data = NULL;
+ } else {
+ r = yp_first(__ypdomain, "passwd.byname",
+ &__ypcurrent, &__ypcurrentlen,
+ &data, &datalen);
+ /*printf("yp_first %d\n", r);*/
+ switch(r) {
+ case 0:
+ break;
+ default:
+ __ypmode = 0;
+ free(data);
+ goto again;
+ }
+ bcopy(data, line, datalen);
+ free(data);
+ data = NULL;
+ }
+ line[datalen] = '\0';
+ /*printf("line = %s\n", line);*/
+ bp = line;
+ goto parse;
+ }
+#endif
+
++_pw_keynum;
bf[0] = _PW_KEYBYNUM;
bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
key.data = (u_char *)bf;
key.size = sizeof(_pw_keynum) + 1;
- return(__hashpw(&key) ? &_pw_passwd : (struct passwd *)NULL);
+ if(__hashpw(&key)) {
+#ifdef YP
+ if(strcmp(_pw_passwd.pw_name, "+") == 0) {
+ __ypmode = 1;
+ goto again;
+ }
+#endif
+ return &_pw_passwd;
+ }
+ return (struct passwd *)NULL;
+
+#ifdef YP
+parse:
+ _pw_passwd.pw_name = strsep(&bp, ":\n");
+ _pw_passwd.pw_passwd = strsep(&bp, ":\n");
+ if (!(cp = strsep(&bp, ":\n")))
+ goto again;
+ _pw_passwd.pw_uid = atoi(cp);
+ if (!(cp = strsep(&bp, ":\n")))
+ goto again;
+ _pw_passwd.pw_gid = atoi(cp);
+ _pw_passwd.pw_change = 0;
+ _pw_passwd.pw_class = "";
+ _pw_passwd.pw_gecos = strsep(&bp, ":\n");
+ _pw_passwd.pw_dir = strsep(&bp, ":\n");
+ _pw_passwd.pw_shell = strsep(&bp, ":\n");
+ _pw_passwd.pw_expire = 0;
+ return &_pw_passwd;
+#endif
}
struct passwd *
@@ -81,6 +209,70 @@ getpwnam(name)
if (!_pw_db && !__initdb())
return((struct passwd *)NULL);
+#ifdef YP
+ bf[0] = _PW_KEYBYNAME;
+ len = strlen("+");
+ bcopy("+", bf + 1, MIN(len, UT_NAMESIZE));
+ key.data = (u_char *)bf;
+ key.size = len + 1;
+
+ /*
+ * If there is a user called "+", then YP is active. In that
+ * case we must sequence through the passwd file in sequence.
+ */
+ if ( __hashpw(&key)) {
+ int r;
+
+ for(_pw_keynum=1; _pw_keynum; _pw_keynum++) {
+ bf[0] = _PW_KEYBYNUM;
+ bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
+ key.data = (u_char *)bf;
+ key.size = sizeof(_pw_keynum) + 1;
+ if(__hashpw(&key) == 0)
+ break;
+ if(strcmp(_pw_passwd.pw_name, "+") == 0) {
+ if(!__ypdomain) {
+ if(_yp_check(&__ypdomain) == 0) {
+ continue;
+ }
+ }
+ if(__ypcurrent) {
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ }
+ r = yp_match(__ypdomain, "passwd.byname",
+ name, strlen(name),
+ &__ypcurrent, &__ypcurrentlen);
+ switch(r) {
+ case 0:
+ break;
+ default:
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ continue;
+ }
+ bcopy(__ypcurrent, line, __ypcurrentlen);
+ line[__ypcurrentlen] = '\0';
+ if(__ypparse(&_pw_passwd, line))
+ continue;
+ }
+ if( strcmp(_pw_passwd.pw_name, name) == 0) {
+ if (!_pw_stayopen) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+ return &_pw_passwd;
+ }
+ continue;
+ }
+ if (!_pw_stayopen) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+ return (struct passwd *)NULL;
+ }
+#endif /* YP */
+
bf[0] = _PW_KEYBYNAME;
len = strlen(name);
bcopy(name, bf + 1, MIN(len, UT_NAMESIZE));
@@ -104,12 +296,78 @@ getpwuid(uid)
#endif
{
DBT key;
- int keyuid, rval;
- char bf[sizeof(keyuid) + 1];
+ char bf[sizeof(_pw_keynum) + 1];
+ int keyuid, rval, len;
if (!_pw_db && !__initdb())
return((struct passwd *)NULL);
+#ifdef YP
+ bf[0] = _PW_KEYBYNAME;
+ len = strlen("+");
+ bcopy("+", bf + 1, MIN(len, UT_NAMESIZE));
+ key.data = (u_char *)bf;
+ key.size = len + 1;
+
+ /*
+ * If there is a user called "+", then YP is active. In that
+ * case we must sequence through the passwd file in sequence.
+ */
+ if ( __hashpw(&key)) {
+ char uidbuf[20];
+ int r;
+
+ for(_pw_keynum=1; _pw_keynum; _pw_keynum++) {
+ bf[0] = _PW_KEYBYNUM;
+ bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum));
+ key.data = (u_char *)bf;
+ key.size = sizeof(_pw_keynum) + 1;
+ if(__hashpw(&key) == 0)
+ break;
+ if(strcmp(_pw_passwd.pw_name, "+") == 0) {
+ if(!__ypdomain) {
+ if(_yp_check(&__ypdomain) == 0) {
+ continue;
+ }
+ }
+ if(__ypcurrent) {
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ }
+ sprintf(uidbuf, "%d", uid);
+ r = yp_match(__ypdomain, "passwd.byuid",
+ uidbuf, strlen(uidbuf),
+ &__ypcurrent, &__ypcurrentlen);
+ switch(r) {
+ case 0:
+ break;
+ default:
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ continue;
+ }
+ bcopy(__ypcurrent, line, __ypcurrentlen);
+ line[__ypcurrentlen] = '\0';
+ if(__ypparse(&_pw_passwd, line))
+ continue;
+ }
+ if( _pw_passwd.pw_uid == uid) {
+ if (!_pw_stayopen) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+ return &_pw_passwd;
+ }
+ continue;
+ }
+ if (!_pw_stayopen) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+ return (struct passwd *)NULL;
+ }
+#endif /* YP */
+
bf[0] = _PW_KEYBYUID;
keyuid = uid;
bcopy(&keyuid, bf + 1, sizeof(keyuid));
@@ -130,15 +388,19 @@ setpassent(stayopen)
{
_pw_keynum = 0;
_pw_stayopen = stayopen;
+#ifdef YP
+ __ypmode = 0;
+ if(__ypcurrent)
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+#endif
return(1);
}
-int
+void
setpwent()
{
- _pw_keynum = 0;
- _pw_stayopen = 0;
- return(1);
+ (void) setpassent(0);
}
void
@@ -149,9 +411,15 @@ endpwent()
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
}
+#ifdef YP
+ __ypmode = 0;
+ if(__ypcurrent)
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+#endif
}
-static
+static int
__initdb()
{
static int warned;
@@ -166,7 +434,7 @@ __initdb()
return(0);
}
-static
+static int
__hashpw(key)
DBT *key;
{
diff --git a/lib/libc/gen/isctype.c b/lib/libc/gen/isctype.c
index e598f1069d12..d8dd5bc33e9f 100644
--- a/lib/libc/gen/isctype.c
+++ b/lib/libc/gen/isctype.c
@@ -1,4 +1,13 @@
/*
+ * Copyright (c) UNIX System Laboratories, Inc. All or some portions
+ * of this file are derived from material licensed to the
+ * University of California by American Telephone and Telegraph Co.
+ * or UNIX System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * $Id: isctype.c,v 1.1.1.1.2.1 1994/05/04 07:39:44 rgrimes Exp $
+ */
+/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
@@ -30,12 +39,6 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
- * -------------------- ----- ----------------------
- * CURRENT PATCH LEVEL: 1 00027
- * -------------------- ----- ----------------------
- *
- * 02 Aug 92 Wiljo Heinen Fixed toupper()/tolower() range check
*/
#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/gen/isupper.3 b/lib/libc/gen/isupper.3
index a9ac34b089a5..22d39e2114fe 100644
--- a/lib/libc/gen/isupper.3
+++ b/lib/libc/gen/isupper.3
@@ -44,7 +44,7 @@
.Sh SYNOPSIS
.Fd #include <ctype.h>
.Ft int
-.Fn supper "int c"
+.Fn isupper "int c"
.Sh DESCRIPTION
The
.Fn isupper
diff --git a/lib/libc/gen/ldexp.3 b/lib/libc/gen/ldexp.3
index 7b96ef4871fa..9920fc45a2f2 100644
--- a/lib/libc/gen/ldexp.3
+++ b/lib/libc/gen/ldexp.3
@@ -40,7 +40,7 @@
.Os
.Sh NAME
.Nm ldexp
-.Nd mutliply floating-point number by integral power of 2
+.Nd multiply floating-point number by integral power of 2
.Sh SYNOPSIS
.Fd #include <math.h>
.Ft double
diff --git a/lib/libc/gen/msgctl.c b/lib/libc/gen/msgctl.c
new file mode 100644
index 000000000000..7b74c51e2466
--- /dev/null
+++ b/lib/libc/gen/msgctl.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#if __STDC__
+int msgctl(int msqid, int cmd, struct msqid_ds *buf)
+#else
+int msgctl(msqid,cmd,buf)
+ int msqid;
+ int cmd;
+ caddr_t buf;
+#endif
+{
+ return (msgsys(0, msqid, cmd, buf));
+}
diff --git a/lib/libc/gen/msgget.c b/lib/libc/gen/msgget.c
new file mode 100644
index 000000000000..3e146b05cbe6
--- /dev/null
+++ b/lib/libc/gen/msgget.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#if __STDC__
+int msgget(key_t key, int msgflg)
+#else
+int msgget(key,msgflg)
+ key_t key;
+ int msgflg;
+#endif
+{
+ return (msgsys(1, key, msgflg));
+}
diff --git a/lib/libc/gen/msgrcv.c b/lib/libc/gen/msgrcv.c
new file mode 100644
index 000000000000..5c1e387d1439
--- /dev/null
+++ b/lib/libc/gen/msgrcv.c
@@ -0,0 +1,17 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#if __STDC__
+int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
+#else
+int msgrcv(msqid, msgp, msgsz, msgtyp, msgflg)
+ int msqid;
+ void *msgp;
+ size_t msgsz;
+ long msgtyp;
+ int msgflg;
+#endif
+{
+ return (msgsys(3, msqid, msgp, msgsz, msgtyp, msgflg));
+}
diff --git a/lib/libc/gen/msgsnd.c b/lib/libc/gen/msgsnd.c
new file mode 100644
index 000000000000..a6209159ff50
--- /dev/null
+++ b/lib/libc/gen/msgsnd.c
@@ -0,0 +1,16 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#if __STDC__
+int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg)
+#else
+int msgsnd(msqid, msgp, msgsz, msgflg)
+ int msqid;
+ void *msgp;
+ size_t msgsz;
+ int msgflg;
+#endif
+{
+ return (msgsys(2, msqid, msgp, msgsz, msgflg));
+}
diff --git a/lib/libc/gen/nlist.3 b/lib/libc/gen/nlist.3
index 4e4fe24c1c90..4d0bdf302139 100644
--- a/lib/libc/gen/nlist.3
+++ b/lib/libc/gen/nlist.3
@@ -46,7 +46,7 @@ The
.Fn nlist
function
retrieves name list entries from the symbol table of an
-exectutable file. (See
+executable file. (See
.Xr a.out 5 . )
The argument
.Fa \&nl
diff --git a/lib/libc/gen/regexp.3 b/lib/libc/gen/regexp.3
deleted file mode 100644
index c78082bb8b0d..000000000000
--- a/lib/libc/gen/regexp.3
+++ /dev/null
@@ -1,315 +0,0 @@
-.\" Copyright 1991 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)regexp.3 5.2 (Berkeley) 4/19/91
-.\"
-.Dd April 19, 1991
-.Dt REGEXP 3
-.Os
-.Sh NAME
-.Nm regcomp ,
-.Nm regexec ,
-.Nm regsub ,
-.Nm regerror
-.Nd regular expression handlers
-.Sh SYNOPSIS
-.Fd #include <regexp.h>
-.Ft regexp *
-.Fn regcomp "const char *exp"
-.Ft int
-.Fn regexec "const regexp *prog" "const char *string"
-.Ft void
-.Fn regsub "const regexp *prog" "const char *source" "char *dest"
-.Sh DESCRIPTION
-The
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-functions
-implement
-.Xr egrep 1 Ns -style
-regular expressions and supporting facilities.
-.Pp
-The
-.Fn regcomp
-function
-compiles a regular expression into a structure of type
-.Xr regexp ,
-and returns a pointer to it.
-The space has been allocated using
-.Xr malloc 3
-and may be released by
-.Xr free .
-.Pp
-The
-.Fn regexec
-function
-matches a
-.Dv NUL Ns -terminated
-.Fa string
-against the compiled regular expression
-in
-.Fa prog .
-It returns 1 for success and 0 for failure, and adjusts the contents of
-.Fa prog Ns 's
-.Em startp
-and
-.Em endp
-(see below) accordingly.
-.Pp
-The members of a
-.Xr regexp
-structure include at least the following (not necessarily in order):
-.Bd -literal -offset indent
-char *startp[NSUBEXP];
-char *endp[NSUBEXP];
-.Ed
-.Pp
-where
-.Dv NSUBEXP
-is defined (as 10) in the header file.
-Once a successful
-.Fn regexec
-has been done using the
-.Fn regexp ,
-each
-.Em startp Ns - Em endp
-pair describes one substring
-within the
-.Fa string ,
-with the
-.Em startp
-pointing to the first character of the substring and
-the
-.Em endp
-pointing to the first character following the substring.
-The 0th substring is the substring of
-.Fa string
-that matched the whole
-regular expression.
-The others are those substrings that matched parenthesized expressions
-within the regular expression, with parenthesized expressions numbered
-in left-to-right order of their opening parentheses.
-.Pp
-The
-.Fn regsub
-function
-copies
-.Fa source
-to
-.Fa dest ,
-making substitutions according to the
-most recent
-.Fn regexec
-performed using
-.Fa prog .
-Each instance of `&' in
-.Fa source
-is replaced by the substring
-indicated by
-.Em startp Ns Bq
-and
-.Em endp Ns Bq .
-Each instance of
-.Sq \e Ns Em n ,
-where
-.Em n
-is a digit, is replaced by
-the substring indicated by
-.Em startp Ns Bq Em n
-and
-.Em endp Ns Bq Em n .
-To get a literal `&' or
-.Sq \e Ns Em n
-into
-.Fa dest ,
-prefix it with `\e';
-to get a literal `\e' preceding `&' or
-.Sq \e Ns Em n ,
-prefix it with
-another `\e'.
-.Pp
-The
-.Fn regerror
-function
-is called whenever an error is detected in
-.Fn regcomp ,
-.Fn regexec ,
-or
-.Fn regsub .
-The default
-.Fn regerror
-writes the string
-.Fa msg ,
-with a suitable indicator of origin,
-on the standard
-error output
-and invokes
-.Xr exit 2 .
-The
-.Fn regerror
-function
-can be replaced by the user if other actions are desirable.
-.Sh REGULAR EXPRESSION SYNTAX
-A regular expression is zero or more
-.Em branches ,
-separated by `|'.
-It matches anything that matches one of the branches.
-.Pp
-A branch is zero or more
-.Em pieces ,
-concatenated.
-It matches a match for the first, followed by a match for the second, etc.
-.Pp
-A piece is an
-.Em atom
-possibly followed by `*', `+', or `?'.
-An atom followed by `*' matches a sequence of 0 or more matches of the atom.
-An atom followed by `+' matches a sequence of 1 or more matches of the atom.
-An atom followed by `?' matches a match of the atom, or the null string.
-.Pp
-An atom is a regular expression in parentheses (matching a match for the
-regular expression), a
-.Em range
-(see below), `.'
-(matching any single character), `^' (matching the null string at the
-beginning of the input string), `$' (matching the null string at the
-end of the input string), a `\e' followed by a single character (matching
-that character), or a single character with no other significance
-(matching that character).
-.Pp
-A
-.Em range
-is a sequence of characters enclosed in `[]'.
-It normally matches any single character from the sequence.
-If the sequence begins with `^',
-it matches any single character
-.Em not
-from the rest of the sequence.
-If two characters in the sequence are separated by `\-', this is shorthand
-for the full list of
-.Tn ASCII
-characters between them
-(e.g. `[0-9]' matches any decimal digit).
-To include a literal `]' in the sequence, make it the first character
-(following a possible `^').
-To include a literal `\-', make it the first or last character.
-.Sh AMBIGUITY
-If a regular expression could match two different parts of the input string,
-it will match the one which begins earliest.
-If both begin in the same place but match different lengths, or match
-the same length in different ways, life gets messier, as follows.
-.Pp
-In general, the possibilities in a list of branches are considered in
-left-to-right order, the possibilities for `*', `+', and `?' are
-considered longest-first, nested constructs are considered from the
-outermost in, and concatenated constructs are considered leftmost-first.
-The match that will be chosen is the one that uses the earliest
-possibility in the first choice that has to be made.
-If there is more than one choice, the next will be made in the same manner
-(earliest possibility) subject to the decision on the first choice.
-And so forth.
-.Pp
-For example,
-.Sq Li (ab|a)b*c
-could match
-`abc' in one of two ways.
-The first choice is between `ab' and `a'; since `ab' is earlier, and does
-lead to a successful overall match, it is chosen.
-Since the `b' is already spoken for,
-the `b*' must match its last possibility\(emthe empty string\(emsince
-it must respect the earlier choice.
-.Pp
-In the particular case where no `|'s are present and there is only one
-`*', `+', or `?', the net effect is that the longest possible
-match will be chosen.
-So
-.Sq Li ab* ,
-presented with `xabbbby', will match `abbbb'.
-Note that if
-.Sq Li ab* ,
-is tried against `xabyabbbz', it
-will match `ab' just after `x', due to the begins-earliest rule.
-(In effect, the decision on where to start the match is the first choice
-to be made, hence subsequent choices must respect it even if this leads them
-to less-preferred alternatives.)
-.Sh RETURN VALUES
-The
-.Fn regcomp
-function
-returns
-.Dv NULL
-for a failure
-.Pf ( Fn regerror
-permitting),
-where failures are syntax errors, exceeding implementation limits,
-or applying `+' or `*' to a possibly-null operand.
-.Sh SEE ALSO
-.Xr ed 1 ,
-.Xr ex 1 ,
-.Xr expr 1 ,
-.Xr egrep 1 ,
-.Xr fgrep 1 ,
-.Xr grep 1 ,
-.Xr regex 3
-.Sh HISTORY
-Both code and manual page for
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-were written at the University of Toronto
-and appeared in
-.Bx 4.3 tahoe .
-They are intended to be compatible with the Bell V8
-.Xr regexp 3 ,
-but are not derived from Bell code.
-.Sh BUGS
-Empty branches and empty regular expressions are not portable to V8.
-.Pp
-The restriction against
-applying `*' or `+' to a possibly-null operand is an artifact of the
-simplistic implementation.
-.Pp
-Does not support
-.Xr egrep Ns 's
-newline-separated branches;
-neither does the V8
-.Xr regexp 3 ,
-though.
-.Pp
-Due to emphasis on
-compactness and simplicity,
-it's not strikingly fast.
-It does give special attention to handling simple cases quickly.
diff --git a/lib/libc/gen/regexp/COPYRIGHT b/lib/libc/gen/regexp/COPYRIGHT
deleted file mode 100644
index 48b3f4339171..000000000000
--- a/lib/libc/gen/regexp/COPYRIGHT
+++ /dev/null
@@ -1,22 +0,0 @@
-This entire subtree is copyright the University of Toronto.
-The following copyright notice applies to all files found here. None of
-these files contain AT&T proprietary source code.
-_____________________________________________________________________________
-
- Copyright (c) 1986 by University of Toronto.
- Written by Henry Spencer. Not derived from licensed software.
-
- Permission is granted to anyone to use this software for any
- purpose on any computer system, and to redistribute it freely,
- subject to the following restrictions:
-
- 1. The author is not responsible for the consequences of use of
- this software, no matter how awful, even if they arise
- from defects in it.
-
- 2. The origin of this software must not be misrepresented, either
- by explicit claim or by omission.
-
- 3. Altered versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
diff --git a/lib/libc/gen/regexp/README b/lib/libc/gen/regexp/README
deleted file mode 100644
index 37d6f51c7119..000000000000
--- a/lib/libc/gen/regexp/README
+++ /dev/null
@@ -1,84 +0,0 @@
-This is a nearly-public-domain reimplementation of the V8 regexp(3) package.
-It gives C programs the ability to use egrep-style regular expressions, and
-does it in a much cleaner fashion than the analogous routines in SysV.
-
- Copyright (c) 1986 by University of Toronto.
- Written by Henry Spencer. Not derived from licensed software.
-
- Permission is granted to anyone to use this software for any
- purpose on any computer system, and to redistribute it freely,
- subject to the following restrictions:
-
- 1. The author is not responsible for the consequences of use of
- this software, no matter how awful, even if they arise
- from defects in it.
-
- 2. The origin of this software must not be misrepresented, either
- by explicit claim or by omission.
-
- 3. Altered versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
-Barring a couple of small items in the BUGS list, this implementation is
-believed 100% compatible with V8. It should even be binary-compatible,
-sort of, since the only fields in a "struct regexp" that other people have
-any business touching are declared in exactly the same way at the same
-location in the struct (the beginning).
-
-This implementation is *NOT* AT&T/Bell code, and is not derived from licensed
-software. Even though U of T is a V8 licensee. This software is based on
-a V8 manual page sent to me by Dennis Ritchie (the manual page enclosed
-here is a complete rewrite and hence is not covered by AT&T copyright).
-The software was nearly complete at the time of arrival of our V8 tape.
-I haven't even looked at V8 yet, although a friend elsewhere at U of T has
-been kind enough to run a few test programs using the V8 regexp(3) to resolve
-a few fine points. I admit to some familiarity with regular-expression
-implementations of the past, but the only one that this code traces any
-ancestry to is the one published in Kernighan & Plauger (from which this
-one draws ideas but not code).
-
-Simplistically: put this stuff into a source directory, copy regexp.h into
-/usr/include, inspect Makefile for compilation options that need changing
-to suit your local environment, and then do "make r". This compiles the
-regexp(3) functions, compiles a test program, and runs a large set of
-regression tests. If there are no complaints, then put regexp.o, regsub.o,
-and regerror.o into your C library, and regexp.3 into your manual-pages
-directory.
-
-Note that if you don't put regexp.h into /usr/include *before* compiling,
-you'll have to add "-I." to CFLAGS before compiling.
-
-The files are:
-
-Makefile instructions to make everything
-regexp.3 manual page
-regexp.h header file, for /usr/include
-regexp.c source for regcomp() and regexec()
-regsub.c source for regsub()
-regerror.c source for default regerror()
-regmagic.h internal header file
-try.c source for test program
-timer.c source for timing program
-tests test list for try and timer
-
-This implementation uses nondeterministic automata rather than the
-deterministic ones found in some other implementations, which makes it
-simpler, smaller, and faster at compiling regular expressions, but slower
-at executing them. In theory, anyway. This implementation does employ
-some special-case optimizations to make the simpler cases (which do make
-up the bulk of regular expressions actually used) run quickly. In general,
-if you want blazing speed you're in the wrong place. Replacing the insides
-of egrep with this stuff is probably a mistake; if you want your own egrep
-you're going to have to do a lot more work. But if you want to use regular
-expressions a little bit in something else, you're in luck. Note that many
-existing text editors use nondeterministic regular-expression implementations,
-so you're in good company.
-
-This stuff should be pretty portable, given appropriate option settings.
-If your chars have less than 8 bits, you're going to have to change the
-internal representation of the automaton, although knowledge of the details
-of this is fairly localized. There are no "reserved" char values except for
-NUL, and no special significance is attached to the top bit of chars.
-The string(3) functions are used a fair bit, on the grounds that they are
-probably faster than coding the operations in line. Some attempts at code
-tuning have been made, but this is invariably a bit machine-specific.
diff --git a/lib/libc/gen/regexp/regerror.c b/lib/libc/gen/regexp/regerror.c
deleted file mode 100644
index 6d0077d63429..000000000000
--- a/lib/libc/gen/regexp/regerror.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <regexp.h>
-#include <stdio.h>
-
-void
-regerror(s)
-const char *s;
-{
-#ifdef ERRAVAIL
- error("regexp: %s", s);
-#else
-/*
- fprintf(stderr, "regexp(3): %s\n", s);
- exit(1);
-*/
- return; /* let std. egrep handle errors */
-#endif
- /* NOTREACHED */
-}
diff --git a/lib/libc/gen/regexp/regexp.3 b/lib/libc/gen/regexp/regexp.3
deleted file mode 100644
index b25fb4b498c6..000000000000
--- a/lib/libc/gen/regexp/regexp.3
+++ /dev/null
@@ -1,315 +0,0 @@
-.\" Copyright 1991 The Regents of the University of California.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)regexp.3 5.2 (Berkeley) 4/20/91
-.\"
-.Dd April 20, 1991
-.Dt REGEXP 3
-.Os
-.Sh NAME
-.Nm regcomp ,
-.Nm regexec ,
-.Nm regsub ,
-.Nm regerror
-.Nd regular expression handlers
-.Sh SYNOPSIS
-.Fd #include <regexp.h>
-.Ft regexp *
-.Fn regcomp "const char *exp"
-.Ft int
-.Fn regexec "const regexp *prog" "const char *string"
-.Ft void
-.Fn regsub "const regexp *prog" "const char *source" "char *dest"
-.Sh DESCRIPTION
-The
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-functions
-implement
-.Xr egrep 1 Ns -style
-regular expressions and supporting facilities.
-.Pp
-The
-.Fn regcomp
-function
-compiles a regular expression into a structure of type
-.Xr regexp ,
-and returns a pointer to it.
-The space has been allocated using
-.Xr malloc 3
-and may be released by
-.Xr free .
-.Pp
-The
-.Fn regexec
-function
-matches a
-.Dv NUL Ns -terminated
-.Fa string
-against the compiled regular expression
-in
-.Fa prog .
-It returns 1 for success and 0 for failure, and adjusts the contents of
-.Fa prog Ns 's
-.Em startp
-and
-.Em endp
-(see below) accordingly.
-.Pp
-The members of a
-.Xr regexp
-structure include at least the following (not necessarily in order):
-.Bd -literal -offset indent
-char *startp[NSUBEXP];
-char *endp[NSUBEXP];
-.Ed
-.Pp
-where
-.Dv NSUBEXP
-is defined (as 10) in the header file.
-Once a successful
-.Fn regexec
-has been done using the
-.Fn regexp ,
-each
-.Em startp Ns - Em endp
-pair describes one substring
-within the
-.Fa string ,
-with the
-.Em startp
-pointing to the first character of the substring and
-the
-.Em endp
-pointing to the first character following the substring.
-The 0th substring is the substring of
-.Fa string
-that matched the whole
-regular expression.
-The others are those substrings that matched parenthesized expressions
-within the regular expression, with parenthesized expressions numbered
-in left-to-right order of their opening parentheses.
-.Pp
-The
-.Fn regsub
-function
-copies
-.Fa source
-to
-.Fa dest ,
-making substitutions according to the
-most recent
-.Fn regexec
-performed using
-.Fa prog .
-Each instance of `&' in
-.Fa source
-is replaced by the substring
-indicated by
-.Em startp Ns Bq
-and
-.Em endp Ns Bq .
-Each instance of
-.Sq \e Ns Em n ,
-where
-.Em n
-is a digit, is replaced by
-the substring indicated by
-.Em startp Ns Bq Em n
-and
-.Em endp Ns Bq Em n .
-To get a literal `&' or
-.Sq \e Ns Em n
-into
-.Fa dest ,
-prefix it with `\e';
-to get a literal `\e' preceding `&' or
-.Sq \e Ns Em n ,
-prefix it with
-another `\e'.
-.Pp
-The
-.Fn regerror
-function
-is called whenever an error is detected in
-.Fn regcomp ,
-.Fn regexec ,
-or
-.Fn regsub .
-The default
-.Fn regerror
-writes the string
-.Fa msg ,
-with a suitable indicator of origin,
-on the standard
-error output
-and invokes
-.Xr exit 2 .
-The
-.Fn regerror
-function
-can be replaced by the user if other actions are desirable.
-.Sh REGULAR EXPRESSION SYNTAX
-A regular expression is zero or more
-.Em branches ,
-separated by `|'.
-It matches anything that matches one of the branches.
-.Pp
-A branch is zero or more
-.Em pieces ,
-concatenated.
-It matches a match for the first, followed by a match for the second, etc.
-.Pp
-A piece is an
-.Em atom
-possibly followed by `*', `+', or `?'.
-An atom followed by `*' matches a sequence of 0 or more matches of the atom.
-An atom followed by `+' matches a sequence of 1 or more matches of the atom.
-An atom followed by `?' matches a match of the atom, or the null string.
-.Pp
-An atom is a regular expression in parentheses (matching a match for the
-regular expression), a
-.Em range
-(see below), `.'
-(matching any single character), `^' (matching the null string at the
-beginning of the input string), `$' (matching the null string at the
-end of the input string), a `\e' followed by a single character (matching
-that character), or a single character with no other significance
-(matching that character).
-.Pp
-A
-.Em range
-is a sequence of characters enclosed in `[]'.
-It normally matches any single character from the sequence.
-If the sequence begins with `^',
-it matches any single character
-.Em not
-from the rest of the sequence.
-If two characters in the sequence are separated by `\-', this is shorthand
-for the full list of
-.Tn ASCII
-characters between them
-(e.g. `[0-9]' matches any decimal digit).
-To include a literal `]' in the sequence, make it the first character
-(following a possible `^').
-To include a literal `\-', make it the first or last character.
-.Sh AMBIGUITY
-If a regular expression could match two different parts of the input string,
-it will match the one which begins earliest.
-If both begin in the same place but match different lengths, or match
-the same length in different ways, life gets messier, as follows.
-.Pp
-In general, the possibilities in a list of branches are considered in
-left-to-right order, the possibilities for `*', `+', and `?' are
-considered longest-first, nested constructs are considered from the
-outermost in, and concatenated constructs are considered leftmost-first.
-The match that will be chosen is the one that uses the earliest
-possibility in the first choice that has to be made.
-If there is more than one choice, the next will be made in the same manner
-(earliest possibility) subject to the decision on the first choice.
-And so forth.
-.Pp
-For example,
-.Sq Li (ab|a)b*c
-could match
-`abc' in one of two ways.
-The first choice is between `ab' and `a'; since `ab' is earlier, and does
-lead to a successful overall match, it is chosen.
-Since the `b' is already spoken for,
-the `b*' must match its last possibility\(emthe empty string\(emsince
-it must respect the earlier choice.
-.Pp
-In the particular case where no `|'s are present and there is only one
-`*', `+', or `?', the net effect is that the longest possible
-match will be chosen.
-So
-.Sq Li ab* ,
-presented with `xabbbby', will match `abbbb'.
-Note that if
-.Sq Li ab* ,
-is tried against `xabyabbbz', it
-will match `ab' just after `x', due to the begins-earliest rule.
-(In effect, the decision on where to start the match is the first choice
-to be made, hence subsequent choices must respect it even if this leads them
-to less-preferred alternatives.)
-.Sh RETURN VALUES
-The
-.Fn regcomp
-function
-returns
-.Dv NULL
-for a failure
-.Pf ( Fn regerror
-permitting),
-where failures are syntax errors, exceeding implementation limits,
-or applying `+' or `*' to a possibly-null operand.
-.Sh SEE ALSO
-.Xr ed 1 ,
-.Xr ex 1 ,
-.Xr expr 1 ,
-.Xr egrep 1 ,
-.Xr fgrep 1 ,
-.Xr grep 1 ,
-.Xr regex 3
-.Sh HISTORY
-Both code and manual page for
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-were written at the University of Toronto
-and appeared in
-.Bx 4.3 tahoe .
-They are intended to be compatible with the Bell V8
-.Xr regexp 3 ,
-but are not derived from Bell code.
-.Sh BUGS
-Empty branches and empty regular expressions are not portable to V8.
-.Pp
-The restriction against
-applying `*' or `+' to a possibly-null operand is an artifact of the
-simplistic implementation.
-.Pp
-Does not support
-.Xr egrep Ns 's
-newline-separated branches;
-neither does the V8
-.Xr regexp 3 ,
-though.
-.Pp
-Due to emphasis on
-compactness and simplicity,
-it's not strikingly fast.
-It does give special attention to handling simple cases quickly.
diff --git a/lib/libc/gen/regexp/regexp.c b/lib/libc/gen/regexp/regexp.c
deleted file mode 100644
index 0084295bfb37..000000000000
--- a/lib/libc/gen/regexp/regexp.c
+++ /dev/null
@@ -1,1320 +0,0 @@
-/*
- * regcomp and regexec -- regsub and regerror are elsewhere
- *
- * Copyright (c) 1986 by University of Toronto.
- * Written by Henry Spencer. Not derived from licensed software.
- *
- * Permission is granted to anyone to use this software for any
- * purpose on any computer system, and to redistribute it freely,
- * subject to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of
- * this software, no matter how awful, even if they arise
- * from defects in it.
- *
- * 2. The origin of this software must not be misrepresented, either
- * by explicit claim or by omission.
- *
- * 3. Altered versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
- *** to assist in implementing egrep.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
- *** as in BSD grep and ex.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
- *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods,
- *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
- *
- * Beware that some of this code is subtly aware of the way operator
- * precedence is structured in regular expressions. Serious changes in
- * regular-expression syntax might require a total rethink.
- */
-#include <regexp.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include "regmagic.h"
-
-/*
- * The "internal use only" fields in regexp.h are present to pass info from
- * compile to execute that permits the execute phase to run lots faster on
- * simple cases. They are:
- *
- * regstart char that must begin a match; '\0' if none obvious
- * reganch is the match anchored (at beginning-of-line only)?
- * regmust string (pointer into program) that match must include, or NULL
- * regmlen length of regmust string
- *
- * Regstart and reganch permit very fast decisions on suitable starting points
- * for a match, cutting down the work a lot. Regmust permits fast rejection
- * of lines that cannot possibly match. The regmust tests are costly enough
- * that regcomp() supplies a regmust only if the r.e. contains something
- * potentially expensive (at present, the only such thing detected is * or +
- * at the start of the r.e., which can involve a lot of backup). Regmlen is
- * supplied because the test in regexec() needs it and regcomp() is computing
- * it anyway.
- */
-
-/*
- * Structure for regexp "program". This is essentially a linear encoding
- * of a nondeterministic finite-state machine (aka syntax charts or
- * "railroad normal form" in parsing technology). Each node is an opcode
- * plus a "next" pointer, possibly plus an operand. "Next" pointers of
- * all nodes except BRANCH implement concatenation; a "next" pointer with
- * a BRANCH on both ends of it is connecting two alternatives. (Here we
- * have one of the subtle syntax dependencies: an individual BRANCH (as
- * opposed to a collection of them) is never concatenated with anything
- * because of operator precedence.) The operand of some types of node is
- * a literal string; for others, it is a node leading into a sub-FSM. In
- * particular, the operand of a BRANCH node is the first node of the branch.
- * (NB this is *not* a tree structure: the tail of the branch connects
- * to the thing following the set of BRANCHes.) The opcodes are:
- */
-
-/* definition number opnd? meaning */
-#define END 0 /* no End of program. */
-#define BOL 1 /* no Match "" at beginning of line. */
-#define EOL 2 /* no Match "" at end of line. */
-#define ANY 3 /* no Match any one character. */
-#define ANYOF 4 /* str Match any character in this string. */
-#define ANYBUT 5 /* str Match any character not in this string. */
-#define BRANCH 6 /* node Match this alternative, or the next... */
-#define BACK 7 /* no Match "", "next" ptr points backward. */
-#define EXACTLY 8 /* str Match this string. */
-#define NOTHING 9 /* no Match empty string. */
-#define STAR 10 /* node Match this (simple) thing 0 or more times. */
-#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
-#define WORDA 12 /* no Match "" at wordchar, where prev is nonword */
-#define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */
-#define OPEN 20 /* no Mark this point in input as start of #n. */
- /* OPEN+1 is number 1, etc. */
-#define CLOSE 30 /* no Analogous to OPEN. */
-
-/*
- * Opcode notes:
- *
- * BRANCH The set of branches constituting a single choice are hooked
- * together with their "next" pointers, since precedence prevents
- * anything being concatenated to any individual branch. The
- * "next" pointer of the last BRANCH in a choice points to the
- * thing following the whole choice. This is also where the
- * final "next" pointer of each individual branch points; each
- * branch starts with the operand node of a BRANCH node.
- *
- * BACK Normal "next" pointers all implicitly point forward; BACK
- * exists to make loop structures possible.
- *
- * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
- * BRANCH structures using BACK. Simple cases (one character
- * per match) are implemented with STAR and PLUS for speed
- * and to minimize recursive plunges.
- *
- * OPEN,CLOSE ...are numbered at compile time.
- */
-
-/*
- * A node is one char of opcode followed by two chars of "next" pointer.
- * "Next" pointers are stored as two 8-bit pieces, high order first. The
- * value is a positive offset from the opcode of the node containing it.
- * An operand, if any, simply follows the node. (Note that much of the
- * code generation knows about this implicit relationship.)
- *
- * Using two bytes for the "next" pointer is vast overkill for most things,
- * but allows patterns to get big without disasters.
- */
-#define OP(p) (*(p))
-#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
-#define OPERAND(p) ((p) + 3)
-
-/*
- * See regmagic.h for one further detail of program structure.
- */
-
-
-/*
- * Utility definitions.
- */
-#ifndef CHARBITS
-#define UCHARAT(p) ((int)*(unsigned char *)(p))
-#else
-#define UCHARAT(p) ((int)*(p)&CHARBITS)
-#endif
-
-#define FAIL(m) { regerror(m); return(NULL); }
-#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
-
-/*
- * Flags to be passed up and down.
- */
-#define HASWIDTH 01 /* Known never to match null string. */
-#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
-#define SPSTART 04 /* Starts with * or +. */
-#define WORST 0 /* Worst case. */
-
-/*
- * Global work variables for regcomp().
- */
-static char *regparse; /* Input-scan pointer. */
-static int regnpar; /* () count. */
-static char regdummy;
-static char *regcode; /* Code-emit pointer; &regdummy = don't. */
-static long regsize; /* Code size. */
-
-/*
- * Forward declarations for regcomp()'s friends.
- */
-#ifndef STATIC
-#define STATIC static
-#endif
-STATIC char *reg();
-STATIC char *regbranch();
-STATIC char *regpiece();
-STATIC char *regatom();
-STATIC char *regnode();
-STATIC char *regnext();
-STATIC void regc();
-STATIC void reginsert();
-STATIC void regtail();
-STATIC void regoptail();
-#ifdef STRCSPN
-STATIC int strcspn();
-#endif
-
-/*
- - regcomp - compile a regular expression into internal code
- *
- * We can't allocate space until we know how big the compiled form will be,
- * but we can't compile it (and thus know how big it is) until we've got a
- * place to put the code. So we cheat: we compile it twice, once with code
- * generation turned off and size counting turned on, and once "for real".
- * This also means that we don't allocate space until we are sure that the
- * thing really will compile successfully, and we never have to move the
- * code and thus invalidate pointers into it. (Note that it has to be in
- * one piece because free() must be able to free it all.)
- *
- * Beware that the optimization-preparation code in here knows about some
- * of the structure of the compiled regexp.
- */
-regexp *
-regcomp(exp)
-const char *exp;
-{
- register regexp *r;
- register char *scan;
- register char *longest;
- register int len;
- int flags;
-
- if (exp == NULL)
- FAIL("NULL argument");
-
- /* First pass: determine size, legality. */
-#ifdef notdef
- if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */
-#endif
- regparse = (char *)exp;
- regnpar = 1;
- regsize = 0L;
- regcode = &regdummy;
- regc(MAGIC);
- if (reg(0, &flags) == NULL)
- return(NULL);
-
- /* Small enough for pointer-storage convention? */
- if (regsize >= 32767L) /* Probably could be 65535L. */
- FAIL("regexp too big");
-
- /* Allocate space. */
- r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
- if (r == NULL)
- FAIL("out of space");
-
- /* Second pass: emit code. */
- regparse = (char *)exp;
- regnpar = 1;
- regcode = r->program;
- regc(MAGIC);
- if (reg(0, &flags) == NULL)
- return(NULL);
-
- /* Dig out information for optimizations. */
- r->regstart = '\0'; /* Worst-case defaults. */
- r->reganch = 0;
- r->regmust = NULL;
- r->regmlen = 0;
- scan = r->program+1; /* First BRANCH. */
- if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
- scan = OPERAND(scan);
-
- /* Starting-point info. */
- if (OP(scan) == EXACTLY)
- r->regstart = *OPERAND(scan);
- else if (OP(scan) == BOL)
- r->reganch++;
-
- /*
- * If there's something expensive in the r.e., find the
- * longest literal string that must appear and make it the
- * regmust. Resolve ties in favor of later strings, since
- * the regstart check works with the beginning of the r.e.
- * and avoiding duplication strengthens checking. Not a
- * strong reason, but sufficient in the absence of others.
- */
- if (flags&SPSTART) {
- longest = NULL;
- len = 0;
- for (; scan != NULL; scan = regnext(scan))
- if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
- longest = OPERAND(scan);
- len = strlen(OPERAND(scan));
- }
- r->regmust = longest;
- r->regmlen = len;
- }
- }
-
- return(r);
-}
-
-/*
- - reg - regular expression, i.e. main body or parenthesized thing
- *
- * Caller must absorb opening parenthesis.
- *
- * Combining parenthesis handling with the base level of regular expression
- * is a trifle forced, but the need to tie the tails of the branches to what
- * follows makes it hard to avoid.
- */
-static char *
-reg(paren, flagp)
-int paren; /* Parenthesized? */
-int *flagp;
-{
- register char *ret;
- register char *br;
- register char *ender;
- register int parno;
- int flags;
-
- *flagp = HASWIDTH; /* Tentatively. */
-
- /* Make an OPEN node, if parenthesized. */
- if (paren) {
- if (regnpar >= NSUBEXP)
- FAIL("too many ()");
- parno = regnpar;
- regnpar++;
- ret = regnode(OPEN+parno);
- } else
- ret = NULL;
-
- /* Pick up the branches, linking them together. */
- br = regbranch(&flags);
- if (br == NULL)
- return(NULL);
- if (ret != NULL)
- regtail(ret, br); /* OPEN -> first. */
- else
- ret = br;
- if (!(flags&HASWIDTH))
- *flagp &= ~HASWIDTH;
- *flagp |= flags&SPSTART;
- while (*regparse == '|' || *regparse == '\n') {
- regparse++;
- br = regbranch(&flags);
- if (br == NULL)
- return(NULL);
- regtail(ret, br); /* BRANCH -> BRANCH. */
- if (!(flags&HASWIDTH))
- *flagp &= ~HASWIDTH;
- *flagp |= flags&SPSTART;
- }
-
- /* Make a closing node, and hook it on the end. */
- ender = regnode((paren) ? CLOSE+parno : END);
- regtail(ret, ender);
-
- /* Hook the tails of the branches to the closing node. */
- for (br = ret; br != NULL; br = regnext(br))
- regoptail(br, ender);
-
- /* Check for proper termination. */
- if (paren && *regparse++ != ')') {
- FAIL("unmatched ()");
- } else if (!paren && *regparse != '\0') {
- if (*regparse == ')') {
- FAIL("unmatched ()");
- } else
- FAIL("junk on end"); /* "Can't happen". */
- /* NOTREACHED */
- }
-
- return(ret);
-}
-
-/*
- - regbranch - one alternative of an | operator
- *
- * Implements the concatenation operator.
- */
-static char *
-regbranch(flagp)
-int *flagp;
-{
- register char *ret;
- register char *chain;
- register char *latest;
- int flags;
-
- *flagp = WORST; /* Tentatively. */
-
- ret = regnode(BRANCH);
- chain = NULL;
- while (*regparse != '\0' && *regparse != ')' &&
- *regparse != '\n' && *regparse != '|') {
- latest = regpiece(&flags);
- if (latest == NULL)
- return(NULL);
- *flagp |= flags&HASWIDTH;
- if (chain == NULL) /* First piece. */
- *flagp |= flags&SPSTART;
- else
- regtail(chain, latest);
- chain = latest;
- }
- if (chain == NULL) /* Loop ran zero times. */
- (void) regnode(NOTHING);
-
- return(ret);
-}
-
-/*
- - regpiece - something followed by possible [*+?]
- *
- * Note that the branching code sequences used for ? and the general cases
- * of * and + are somewhat optimized: they use the same NOTHING node as
- * both the endmarker for their branch list and the body of the last branch.
- * It might seem that this node could be dispensed with entirely, but the
- * endmarker role is not redundant.
- */
-static char *
-regpiece(flagp)
-int *flagp;
-{
- register char *ret;
- register char op;
- register char *next;
- int flags;
-
- ret = regatom(&flags);
- if (ret == NULL)
- return(NULL);
-
- op = *regparse;
- if (!ISMULT(op)) {
- *flagp = flags;
- return(ret);
- }
-
- if (!(flags&HASWIDTH) && op != '?')
- FAIL("*+ operand could be empty");
- *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
-
- if (op == '*' && (flags&SIMPLE))
- reginsert(STAR, ret);
- else if (op == '*') {
- /* Emit x* as (x&|), where & means "self". */
- reginsert(BRANCH, ret); /* Either x */
- regoptail(ret, regnode(BACK)); /* and loop */
- regoptail(ret, ret); /* back */
- regtail(ret, regnode(BRANCH)); /* or */
- regtail(ret, regnode(NOTHING)); /* null. */
- } else if (op == '+' && (flags&SIMPLE))
- reginsert(PLUS, ret);
- else if (op == '+') {
- /* Emit x+ as x(&|), where & means "self". */
- next = regnode(BRANCH); /* Either */
- regtail(ret, next);
- regtail(regnode(BACK), ret); /* loop back */
- regtail(next, regnode(BRANCH)); /* or */
- regtail(ret, regnode(NOTHING)); /* null. */
- } else if (op == '?') {
- /* Emit x? as (x|) */
- reginsert(BRANCH, ret); /* Either x */
- regtail(ret, regnode(BRANCH)); /* or */
- next = regnode(NOTHING); /* null. */
- regtail(ret, next);
- regoptail(ret, next);
- }
- regparse++;
- if (ISMULT(*regparse))
- FAIL("nested *?+");
-
- return(ret);
-}
-
-/*
- - regatom - the lowest level
- *
- * Optimization: gobbles an entire sequence of ordinary characters so that
- * it can turn them into a single node, which is smaller to store and
- * faster to run. Backslashed characters are exceptions, each becoming a
- * separate node; the code is simpler that way and it's not worth fixing.
- */
-static char *
-regatom(flagp)
-int *flagp;
-{
- register char *ret;
- int flags;
-
- *flagp = WORST; /* Tentatively. */
-
- switch (*regparse++) {
- /* FIXME: these chars only have meaning at beg/end of pat? */
- case '^':
- ret = regnode(BOL);
- break;
- case '$':
- ret = regnode(EOL);
- break;
- case '.':
- ret = regnode(ANY);
- *flagp |= HASWIDTH|SIMPLE;
- break;
- case '[': {
- register int class;
- register int classend;
-
- if (*regparse == '^') { /* Complement of range. */
- ret = regnode(ANYBUT);
- regparse++;
- } else
- ret = regnode(ANYOF);
- if (*regparse == ']' || *regparse == '-')
- regc(*regparse++);
- while (*regparse != '\0' && *regparse != ']') {
- if (*regparse == '-') {
- regparse++;
- if (*regparse == ']' || *regparse == '\0')
- regc('-');
- else {
- class = UCHARAT(regparse-2)+1;
- classend = UCHARAT(regparse);
- if (class > classend+1)
- FAIL("invalid [] range");
- for (; class <= classend; class++)
- regc(class);
- regparse++;
- }
- } else
- regc(*regparse++);
- }
- regc('\0');
- if (*regparse != ']')
- FAIL("unmatched []");
- regparse++;
- *flagp |= HASWIDTH|SIMPLE;
- }
- break;
- case '(':
- ret = reg(1, &flags);
- if (ret == NULL)
- return(NULL);
- *flagp |= flags&(HASWIDTH|SPSTART);
- break;
- case '\0':
- case '|':
- case '\n':
- case ')':
- FAIL("internal urp"); /* Supposed to be caught earlier. */
- break;
- case '?':
- case '+':
- case '*':
- FAIL("?+* follows nothing");
- break;
- case '\\':
- switch (*regparse++) {
- case '\0':
- FAIL("trailing \\");
- break;
- case '<':
- ret = regnode(WORDA);
- break;
- case '>':
- ret = regnode(WORDZ);
- break;
- /* FIXME: Someday handle \1, \2, ... */
- default:
- /* Handle general quoted chars in exact-match routine */
- goto de_fault;
- }
- break;
- de_fault:
- default:
- /*
- * Encode a string of characters to be matched exactly.
- *
- * This is a bit tricky due to quoted chars and due to
- * '*', '+', and '?' taking the SINGLE char previous
- * as their operand.
- *
- * On entry, the char at regparse[-1] is going to go
- * into the string, no matter what it is. (It could be
- * following a \ if we are entered from the '\' case.)
- *
- * Basic idea is to pick up a good char in ch and
- * examine the next char. If it's *+? then we twiddle.
- * If it's \ then we frozzle. If it's other magic char
- * we push ch and terminate the string. If none of the
- * above, we push ch on the string and go around again.
- *
- * regprev is used to remember where "the current char"
- * starts in the string, if due to a *+? we need to back
- * up and put the current char in a separate, 1-char, string.
- * When regprev is NULL, ch is the only char in the
- * string; this is used in *+? handling, and in setting
- * flags |= SIMPLE at the end.
- */
- {
- char *regprev;
- register char ch;
-
- regparse--; /* Look at cur char */
- ret = regnode(EXACTLY);
- for ( regprev = 0 ; ; ) {
- ch = *regparse++; /* Get current char */
- switch (*regparse) { /* look at next one */
-
- default:
- regc(ch); /* Add cur to string */
- break;
-
- case '.': case '[': case '(':
- case ')': case '|': case '\n':
- case '$': case '^':
- case '\0':
- /* FIXME, $ and ^ should not always be magic */
- magic:
- regc(ch); /* dump cur char */
- goto done; /* and we are done */
-
- case '?': case '+': case '*':
- if (!regprev) /* If just ch in str, */
- goto magic; /* use it */
- /* End mult-char string one early */
- regparse = regprev; /* Back up parse */
- goto done;
-
- case '\\':
- regc(ch); /* Cur char OK */
- switch (regparse[1]){ /* Look after \ */
- case '\0':
- case '<':
- case '>':
- /* FIXME: Someday handle \1, \2, ... */
- goto done; /* Not quoted */
- default:
- /* Backup point is \, scan * point is after it. */
- regprev = regparse;
- regparse++;
- continue; /* NOT break; */
- }
- }
- regprev = regparse; /* Set backup point */
- }
- done:
- regc('\0');
- *flagp |= HASWIDTH;
- if (!regprev) /* One char? */
- *flagp |= SIMPLE;
- }
- break;
- }
-
- return(ret);
-}
-
-/*
- - regnode - emit a node
- */
-static char * /* Location. */
-regnode(op)
-char op;
-{
- register char *ret;
- register char *ptr;
-
- ret = regcode;
- if (ret == &regdummy) {
- regsize += 3;
- return(ret);
- }
-
- ptr = ret;
- *ptr++ = op;
- *ptr++ = '\0'; /* Null "next" pointer. */
- *ptr++ = '\0';
- regcode = ptr;
-
- return(ret);
-}
-
-/*
- - regc - emit (if appropriate) a byte of code
- */
-static void
-regc(b)
-char b;
-{
- if (regcode != &regdummy)
- *regcode++ = b;
- else
- regsize++;
-}
-
-/*
- - reginsert - insert an operator in front of already-emitted operand
- *
- * Means relocating the operand.
- */
-static void
-reginsert(op, opnd)
-char op;
-char *opnd;
-{
- register char *src;
- register char *dst;
- register char *place;
-
- if (regcode == &regdummy) {
- regsize += 3;
- return;
- }
-
- src = regcode;
- regcode += 3;
- dst = regcode;
- while (src > opnd)
- *--dst = *--src;
-
- place = opnd; /* Op node, where operand used to be. */
- *place++ = op;
- *place++ = '\0';
- *place++ = '\0';
-}
-
-/*
- - regtail - set the next-pointer at the end of a node chain
- */
-static void
-regtail(p, val)
-char *p;
-char *val;
-{
- register char *scan;
- register char *temp;
- register int offset;
-
- if (p == &regdummy)
- return;
-
- /* Find last node. */
- scan = p;
- for (;;) {
- temp = regnext(scan);
- if (temp == NULL)
- break;
- scan = temp;
- }
-
- if (OP(scan) == BACK)
- offset = scan - val;
- else
- offset = val - scan;
- *(scan+1) = (offset>>8)&0377;
- *(scan+2) = offset&0377;
-}
-
-/*
- - regoptail - regtail on operand of first argument; nop if operandless
- */
-static void
-regoptail(p, val)
-char *p;
-char *val;
-{
- /* "Operandless" and "op != BRANCH" are synonymous in practice. */
- if (p == NULL || p == &regdummy || OP(p) != BRANCH)
- return;
- regtail(OPERAND(p), val);
-}
-
-/*
- * regexec and friends
- */
-
-/*
- * Global work variables for regexec().
- */
-static char *reginput; /* String-input pointer. */
-static char *regbol; /* Beginning of input, for ^ check. */
-static char **regstartp; /* Pointer to startp array. */
-static char **regendp; /* Ditto for endp. */
-
-/*
- * Forwards.
- */
-STATIC int regtry();
-STATIC int regmatch();
-STATIC int regrepeat();
-
-#ifdef DEBUG
-int regnarrate = 0;
-void regdump();
-STATIC char *regprop();
-#endif
-
-/*
- - regexec - match a regexp against a string
- */
-int
-regexec(prog, string)
-register const regexp *prog;
-register const char *string;
-{
- register char *s;
- extern char *strchr();
-
- /* Be paranoid... */
- if (prog == NULL || string == NULL) {
- regerror("NULL parameter");
- return(0);
- }
-
- /* Check validity of program. */
- if (UCHARAT(prog->program) != MAGIC) {
- regerror("corrupted program");
- return(0);
- }
-
- /* If there is a "must appear" string, look for it. */
- if (prog->regmust != NULL) {
- s = (char *)string;
- while ((s = strchr(s, prog->regmust[0])) != NULL) {
- if (strncmp(s, prog->regmust, prog->regmlen) == 0)
- break; /* Found it. */
- s++;
- }
- if (s == NULL) /* Not present. */
- return(0);
- }
-
- /* Mark beginning of line for ^ . */
- regbol = (char *)string;
-
- /* Simplest case: anchored match need be tried only once. */
- if (prog->reganch)
- return(regtry(prog, string));
-
- /* Messy cases: unanchored match. */
- s = (char *)string;
- if (prog->regstart != '\0')
- /* We know what char it must start with. */
- while ((s = strchr(s, prog->regstart)) != NULL) {
- if (regtry(prog, s))
- return(1);
- s++;
- }
- else
- /* We don't -- general case. */
- do {
- if (regtry(prog, s))
- return(1);
- } while (*s++ != '\0');
-
- /* Failure. */
- return(0);
-}
-
-/*
- - regtry - try match at specific point
- */
-static int /* 0 failure, 1 success */
-regtry(prog, string)
-regexp *prog;
-char *string;
-{
- register int i;
- register char **sp;
- register char **ep;
-
- reginput = string;
- regstartp = prog->startp;
- regendp = prog->endp;
-
- sp = prog->startp;
- ep = prog->endp;
- for (i = NSUBEXP; i > 0; i--) {
- *sp++ = NULL;
- *ep++ = NULL;
- }
- if (regmatch(prog->program + 1)) {
- prog->startp[0] = string;
- prog->endp[0] = reginput;
- return(1);
- } else
- return(0);
-}
-
-/*
- - regmatch - main matching routine
- *
- * Conceptually the strategy is simple: check to see whether the current
- * node matches, call self recursively to see whether the rest matches,
- * and then act accordingly. In practice we make some effort to avoid
- * recursion, in particular by going through "ordinary" nodes (that don't
- * need to know whether the rest of the match failed) by a loop instead of
- * by recursion.
- */
-static int /* 0 failure, 1 success */
-regmatch(prog)
-char *prog;
-{
- register char *scan; /* Current node. */
- char *next; /* Next node. */
- extern char *strchr();
-
- scan = prog;
-#ifdef DEBUG
- if (scan != NULL && regnarrate)
- fprintf(stderr, "%s(\n", regprop(scan));
-#endif
- while (scan != NULL) {
-#ifdef DEBUG
- if (regnarrate)
- fprintf(stderr, "%s...\n", regprop(scan));
-#endif
- next = regnext(scan);
-
- switch (OP(scan)) {
- case BOL:
- if (reginput != regbol)
- return(0);
- break;
- case EOL:
- if (*reginput != '\0')
- return(0);
- break;
- case WORDA:
- /* Must be looking at a letter, digit, or _ */
- if ((!isalnum(*reginput)) && *reginput != '_')
- return(0);
- /* Prev must be BOL or nonword */
- if (reginput > regbol &&
- (isalnum(reginput[-1]) || reginput[-1] == '_'))
- return(0);
- break;
- case WORDZ:
- /* Must be looking at non letter, digit, or _ */
- if (isalnum(*reginput) || *reginput == '_')
- return(0);
- /* We don't care what the previous char was */
- break;
- case ANY:
- if (*reginput == '\0')
- return(0);
- reginput++;
- break;
- case EXACTLY: {
- register int len;
- register char *opnd;
-
- opnd = OPERAND(scan);
- /* Inline the first character, for speed. */
- if (*opnd != *reginput)
- return(0);
- len = strlen(opnd);
- if (len > 1 && strncmp(opnd, reginput, len) != 0)
- return(0);
- reginput += len;
- }
- break;
- case ANYOF:
- if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
- return(0);
- reginput++;
- break;
- case ANYBUT:
- if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
- return(0);
- reginput++;
- break;
- case NOTHING:
- break;
- case BACK:
- break;
- case OPEN+1:
- case OPEN+2:
- case OPEN+3:
- case OPEN+4:
- case OPEN+5:
- case OPEN+6:
- case OPEN+7:
- case OPEN+8:
- case OPEN+9: {
- register int no;
- register char *save;
-
- no = OP(scan) - OPEN;
- save = reginput;
-
- if (regmatch(next)) {
- /*
- * Don't set startp if some later
- * invocation of the same parentheses
- * already has.
- */
- if (regstartp[no] == NULL)
- regstartp[no] = save;
- return(1);
- } else
- return(0);
- }
- break;
- case CLOSE+1:
- case CLOSE+2:
- case CLOSE+3:
- case CLOSE+4:
- case CLOSE+5:
- case CLOSE+6:
- case CLOSE+7:
- case CLOSE+8:
- case CLOSE+9: {
- register int no;
- register char *save;
-
- no = OP(scan) - CLOSE;
- save = reginput;
-
- if (regmatch(next)) {
- /*
- * Don't set endp if some later
- * invocation of the same parentheses
- * already has.
- */
- if (regendp[no] == NULL)
- regendp[no] = save;
- return(1);
- } else
- return(0);
- }
- break;
- case BRANCH: {
- register char *save;
-
- if (OP(next) != BRANCH) /* No choice. */
- next = OPERAND(scan); /* Avoid recursion. */
- else {
- do {
- save = reginput;
- if (regmatch(OPERAND(scan)))
- return(1);
- reginput = save;
- scan = regnext(scan);
- } while (scan != NULL && OP(scan) == BRANCH);
- return(0);
- /* NOTREACHED */
- }
- }
- break;
- case STAR:
- case PLUS: {
- register char nextch;
- register int no;
- register char *save;
- register int min;
-
- /*
- * Lookahead to avoid useless match attempts
- * when we know what character comes next.
- */
- nextch = '\0';
- if (OP(next) == EXACTLY)
- nextch = *OPERAND(next);
- min = (OP(scan) == STAR) ? 0 : 1;
- save = reginput;
- no = regrepeat(OPERAND(scan));
- while (no >= min) {
- /* If it could work, try it. */
- if (nextch == '\0' || *reginput == nextch)
- if (regmatch(next))
- return(1);
- /* Couldn't or didn't -- back up. */
- no--;
- reginput = save + no;
- }
- return(0);
- }
- break;
- case END:
- return(1); /* Success! */
- break;
- default:
- regerror("memory corruption");
- return(0);
- break;
- }
-
- scan = next;
- }
-
- /*
- * We get here only if there's trouble -- normally "case END" is
- * the terminating point.
- */
- regerror("corrupted pointers");
- return(0);
-}
-
-/*
- - regrepeat - repeatedly match something simple, report how many
- */
-static int
-regrepeat(p)
-char *p;
-{
- register int count = 0;
- register char *scan;
- register char *opnd;
-
- scan = reginput;
- opnd = OPERAND(p);
- switch (OP(p)) {
- case ANY:
- count = strlen(scan);
- scan += count;
- break;
- case EXACTLY:
- while (*opnd == *scan) {
- count++;
- scan++;
- }
- break;
- case ANYOF:
- while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
- count++;
- scan++;
- }
- break;
- case ANYBUT:
- while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
- count++;
- scan++;
- }
- break;
- default: /* Oh dear. Called inappropriately. */
- regerror("internal foulup");
- count = 0; /* Best compromise. */
- break;
- }
- reginput = scan;
-
- return(count);
-}
-
-/*
- - regnext - dig the "next" pointer out of a node
- */
-static char *
-regnext(p)
-register char *p;
-{
- register int offset;
-
- if (p == &regdummy)
- return(NULL);
-
- offset = NEXT(p);
- if (offset == 0)
- return(NULL);
-
- if (OP(p) == BACK)
- return(p-offset);
- else
- return(p+offset);
-}
-
-#ifdef DEBUG
-
-STATIC char *regprop();
-
-/*
- - regdump - dump a regexp onto stdout in vaguely comprehensible form
- */
-void
-regdump(r)
-regexp *r;
-{
- register char *s;
- register char op = EXACTLY; /* Arbitrary non-END op. */
- register char *next;
- extern char *strchr();
-
-
- s = r->program + 1;
- while (op != END) { /* While that wasn't END last time... */
- op = OP(s);
- printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
- next = regnext(s);
- if (next == NULL) /* Next ptr. */
- printf("(0)");
- else
- printf("(%d)", (s-r->program)+(next-s));
- s += 3;
- if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
- /* Literal string, where present. */
- while (*s != '\0') {
- putchar(*s);
- s++;
- }
- s++;
- }
- putchar('\n');
- }
-
- /* Header fields of interest. */
- if (r->regstart != '\0')
- printf("start `%c' ", r->regstart);
- if (r->reganch)
- printf("anchored ");
- if (r->regmust != NULL)
- printf("must have \"%s\"", r->regmust);
- printf("\n");
-}
-
-/*
- - regprop - printable representation of opcode
- */
-static char *
-regprop(op)
-char *op;
-{
- register char *p;
- static char buf[50];
-
- (void) strcpy(buf, ":");
-
- switch (OP(op)) {
- case BOL:
- p = "BOL";
- break;
- case EOL:
- p = "EOL";
- break;
- case ANY:
- p = "ANY";
- break;
- case ANYOF:
- p = "ANYOF";
- break;
- case ANYBUT:
- p = "ANYBUT";
- break;
- case BRANCH:
- p = "BRANCH";
- break;
- case EXACTLY:
- p = "EXACTLY";
- break;
- case NOTHING:
- p = "NOTHING";
- break;
- case BACK:
- p = "BACK";
- break;
- case END:
- p = "END";
- break;
- case OPEN+1:
- case OPEN+2:
- case OPEN+3:
- case OPEN+4:
- case OPEN+5:
- case OPEN+6:
- case OPEN+7:
- case OPEN+8:
- case OPEN+9:
- sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
- p = NULL;
- break;
- case CLOSE+1:
- case CLOSE+2:
- case CLOSE+3:
- case CLOSE+4:
- case CLOSE+5:
- case CLOSE+6:
- case CLOSE+7:
- case CLOSE+8:
- case CLOSE+9:
- sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
- p = NULL;
- break;
- case STAR:
- p = "STAR";
- break;
- case PLUS:
- p = "PLUS";
- break;
- case WORDA:
- p = "WORDA";
- break;
- case WORDZ:
- p = "WORDZ";
- break;
- default:
- regerror("corrupted opcode");
- break;
- }
- if (p != NULL)
- (void) strcat(buf, p);
- return(buf);
-}
-#endif
-
-/*
- * The following is provided for those people who do not have strcspn() in
- * their C libraries. They should get off their butts and do something
- * about it; at least one public-domain implementation of those (highly
- * useful) string routines has been published on Usenet.
- */
-#ifdef STRCSPN
-/*
- * strcspn - find length of initial segment of s1 consisting entirely
- * of characters not from s2
- */
-
-static int
-strcspn(s1, s2)
-char *s1;
-char *s2;
-{
- register char *scan1;
- register char *scan2;
- register int count;
-
- count = 0;
- for (scan1 = s1; *scan1 != '\0'; scan1++) {
- for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
- if (*scan1 == *scan2++)
- return(count);
- count++;
- }
- return(count);
-}
-#endif
diff --git a/lib/libc/gen/regexp/regexp.h b/lib/libc/gen/regexp/regexp.h
deleted file mode 100644
index 73d6bf412424..000000000000
--- a/lib/libc/gen/regexp/regexp.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Definitions etc. for regexp(3) routines.
- *
- * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
- * not the System V one.
- */
-#define NSUBEXP 10
-typedef struct regexp {
- char *startp[NSUBEXP];
- char *endp[NSUBEXP];
- char regstart; /* Internal use only. */
- char reganch; /* Internal use only. */
- char *regmust; /* Internal use only. */
- int regmlen; /* Internal use only. */
- char program[1]; /* Unwarranted chumminess with compiler. */
-} regexp;
-
-extern regexp *regcomp();
-extern int regexec();
-extern void regsub();
-extern void regerror();
diff --git a/lib/libc/gen/regexp/regmagic.h b/lib/libc/gen/regexp/regmagic.h
deleted file mode 100644
index 5acf4478ff71..000000000000
--- a/lib/libc/gen/regexp/regmagic.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * The first byte of the regexp internal "program" is actually this magic
- * number; the start node begins in the second byte.
- */
-#define MAGIC 0234
diff --git a/lib/libc/gen/regexp/regsub.c b/lib/libc/gen/regexp/regsub.c
deleted file mode 100644
index e55b9b624d1d..000000000000
--- a/lib/libc/gen/regexp/regsub.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * regsub
- *
- * Copyright (c) 1986 by University of Toronto.
- * Written by Henry Spencer. Not derived from licensed software.
- *
- * Permission is granted to anyone to use this software for any
- * purpose on any computer system, and to redistribute it freely,
- * subject to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of
- * this software, no matter how awful, even if they arise
- * from defects in it.
- *
- * 2. The origin of this software must not be misrepresented, either
- * by explicit claim or by omission.
- *
- * 3. Altered versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- */
-#include <regexp.h>
-#include <stdio.h>
-#include <string.h>
-#include "regmagic.h"
-
-#ifndef CHARBITS
-#define UCHARAT(p) ((int)*(unsigned char *)(p))
-#else
-#define UCHARAT(p) ((int)*(p)&CHARBITS)
-#endif
-
-/*
- - regsub - perform substitutions after a regexp match
- */
-void
-regsub(prog, source, dest)
-const regexp *prog;
-const char *source;
-char *dest;
-{
- register char *src;
- register char *dst;
- register char c;
- register int no;
- register int len;
- extern char *strncpy();
-
- if (prog == NULL || source == NULL || dest == NULL) {
- regerror("NULL parm to regsub");
- return;
- }
- if (UCHARAT(prog->program) != MAGIC) {
- regerror("damaged regexp fed to regsub");
- return;
- }
-
- src = (char *)source;
- dst = dest;
- while ((c = *src++) != '\0') {
- if (c == '&')
- no = 0;
- else if (c == '\\' && '0' <= *src && *src <= '9')
- no = *src++ - '0';
- else
- no = -1;
- if (no < 0) { /* Ordinary character. */
- if (c == '\\' && (*src == '\\' || *src == '&'))
- c = *src++;
- *dst++ = c;
- } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
- len = prog->endp[no] - prog->startp[no];
- (void) strncpy(dst, prog->startp[no], len);
- dst += len;
- if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */
- regerror("damaged match string");
- return;
- }
- }
- }
- *dst++ = '\0';
-}
diff --git a/lib/libc/gen/semconfig.c b/lib/libc/gen/semconfig.c
new file mode 100644
index 000000000000..66fbb2d93398
--- /dev/null
+++ b/lib/libc/gen/semconfig.c
@@ -0,0 +1,13 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if __STDC__
+int semconfig(int cmd, int p1, int p2, int p3)
+#else
+int semctl(cmd, p1, p2, p3)
+ int cmd, p1, p2, p3;
+#endif
+{
+ return (semsys(3, cmd, p1, p2, p3));
+}
diff --git a/lib/libc/gen/semctl.c b/lib/libc/gen/semctl.c
new file mode 100644
index 000000000000..313a1dbeda8f
--- /dev/null
+++ b/lib/libc/gen/semctl.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if __STDC__
+int semctl(int semid, int semnum, int cmd, union semun semun)
+#else
+int semctl(semid, int semnum, cmd, semun)
+ int semid, semnum;
+ int cmd;
+ union semun semun;
+#endif
+{
+ return (semsys(0, semid, semnum, cmd, &semun));
+}
diff --git a/lib/libc/gen/semget.c b/lib/libc/gen/semget.c
new file mode 100644
index 000000000000..81c6a86e438c
--- /dev/null
+++ b/lib/libc/gen/semget.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if __STDC__
+int semget(key_t key, int nsems, int semflg)
+#else
+int semget(key, nsems, semflg)
+ key_t key;
+ int nsems;
+ int semflg;
+#endif
+{
+ return (semsys(1, key, nsems, semflg));
+}
diff --git a/lib/libc/gen/semop.c b/lib/libc/gen/semop.c
new file mode 100644
index 000000000000..0b97c6aacb2f
--- /dev/null
+++ b/lib/libc/gen/semop.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if __STDC__
+int semop(int semid, struct sembuf *sops, unsigned nsops)
+#else
+int semop(semid, sops, nsops)
+ int semid;
+ struct sembuf *sops;
+ unsigned nsops;
+#endif
+{
+ return (semsys(2, semid, sops, nsops, 0));
+}
diff --git a/lib/libc/gen/setmode.c b/lib/libc/gen/setmode.c
index fa688a77b264..12f7c1ab1ca7 100644
--- a/lib/libc/gen/setmode.c
+++ b/lib/libc/gen/setmode.c
@@ -215,7 +215,7 @@ setmode(p)
mode_t mask;
struct bitcmd *set, *saveset, *endset;
int permXbits, setlen;
- static int compress_mode();
+ static void compress_mode();
/*
* Get a copy of the mask for the permissions that are mask relative.
@@ -321,7 +321,7 @@ setmode(p)
* to flush out any partial mode that we have,
* and then do the copying of the mode bits.
*/
- if (perm) {
+ if (perm || op == '=') {
ADDCMD(op, who, perm, mask);
perm = 0;
}
@@ -337,7 +337,7 @@ setmode(p)
* Add any permissions that we haven't already
* done.
*/
- if (perm) {
+ if (perm || op == '=') {
ADDCMD(op, who, perm, mask);
perm = 0;
}
@@ -389,7 +389,7 @@ dumpmode(set)
* 'g' and 'o' commands continue to be separate. They could probably be
* compacted, but it's not worth the effort.
*/
-static
+static void
compress_mode(set)
register struct bitcmd *set;
{
diff --git a/lib/libc/gen/signal.3 b/lib/libc/gen/signal.3
index 7f6570625824..b78797c572bd 100644
--- a/lib/libc/gen/signal.3
+++ b/lib/libc/gen/signal.3
@@ -79,7 +79,7 @@ and
signals, the
.Fn signal
function allows for a signal to be caught, to be ignored, or to generate
-an interupt.
+an interrupt.
These signals are defined in the file
.Aq Pa signal.h :
.Bl -column SIGVTALARMXX "create core imagexxx"
@@ -150,7 +150,7 @@ is called.
.Pp
The handled signal is unblocked with the
function returns and
-the process continues from where it left off when the signal occured.
+the process continues from where it left off when the signal occurred.
.Bf -symbolic
Unlike previous signal facilities, the handler
func() remains installed after a signal has been delivered.
diff --git a/lib/libc/gen/tcgetpgrp.3 b/lib/libc/gen/tcgetpgrp.3
new file mode 100644
index 000000000000..03396104caf6
--- /dev/null
+++ b/lib/libc/gen/tcgetpgrp.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcgetpgrp.3 5.3 (Berkeley) 3/29/92
+.\"
+.Dd "March 29, 1992"
+.Dt TCGETPGRP 3
+.Os
+.Sh NAME
+.Nm tcgetpgrp
+.Nd get foreground process group ID
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft pid_t
+.Fn tcgetpgrp "int fd"
+.Sh DESCRIPTION
+The
+.Nm tcgetpgrp
+function returns the value of the process group ID of the foreground
+process group associated with the terminal device.
+If there is no foreground process group,
+.Nm tcgetpgrp
+returns an invalid process ID.
+.Sh ERRORS
+If an error occurs,
+.Nm tcgetpgrp
+returns -1 and the global variable
+.Va errno
+is set to indicate the error, as follows:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid file descriptor.
+.It Bq Er ENOTTY
+The calling process does not have a controlling terminal or the
+underlying terminal device represented by
+.Fa fd
+is not the controlling terminal.
+.El
+.Sh SEE ALSO
+.Xr setpgid 3 ,
+.Xr setsid 2 ,
+.Xr tcsetpgrp 3
+.Sh STANDARDS
+The
+.Nm tcgetpgrp
+function is expected to be compliant with the
+.St -p1003.1-88
+specification.
diff --git a/lib/libc/gen/tcsetattr.3 b/lib/libc/gen/tcsetattr.3
new file mode 100644
index 000000000000..b206beec6b91
--- /dev/null
+++ b/lib/libc/gen/tcsetattr.3
@@ -0,0 +1,330 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcsetattr.3 5.2 (Berkeley) 3/4/92
+.\"
+.Dd "March 4, 1992"
+.Dt TCSETATTR 3
+.Os
+.Sh NAME
+.Nm cfgetispeed ,
+.Nm cfsetispeed ,
+.Nm cfgetospeed ,
+.Nm cfsetospeed ,
+.Nm cfsetspeed ,
+.Nm cfmakeraw ,
+.Nm tcgetattr ,
+.Nm tcsetattr
+.Nd manipulating the termios structure
+.Sh SYNOPSIS
+.Fd #include <termios.h>
+.Ft speed_t
+.Fn cfgetispeed "struct termios *t"
+.Ft int
+.Fn cfsetispeed "struct termios *t" "speed_t speed"
+.Ft speed_t
+.Fn cfgetospeed "struct termios *t"
+.Ft int
+.Fn cfsetospeed "struct termios *t" "speed_t speed"
+.Ft void
+.Fn cfsetspeed "struct termios *t" "speed_t speed"
+.Ft void
+.Fn cfmakeraw "struct termios *t"
+.Ft int
+.Fn tcgetattr "int fd" "struct termios *t"
+.Ft int
+.Fn tcsetattr "int fd" "int action" "struct termios *t"
+.Sh DESCRIPTION
+The
+.Nm cfmakeraw ,
+.Nm tcgetattr
+and
+.Nm tcsetattr
+functions are provided for getting and setting the termios structure.
+.Pp
+The
+.Nm cfgetispeed ,
+.Nm cfsetispeed ,
+.Nm cfgetospeed ,
+.Nm cfsetospeed
+and
+.Nm cfsetspeed
+functions are provided for getting and setting the baud rate values in
+the termios structure.
+The effects of the functions on the terminal as described below
+do not become effective, nor are all errors detected, until the
+.Nm tcsetattr
+function is called.
+Certain values for baud rates set in the termios structure and passed to
+.Nm tcsetattr
+have special meanings.
+These are discussed in the portion of the manual page that describes the
+.Nm tcsetattr
+function.
+.Sh GETTING AND SETTING THE BAUD RATE
+The input and output baud rates are found in the termios structure.
+The unsigned integer
+.Li speed_t
+is typdef'd in the include file
+.Aq Pa termios.h .
+The value of the integer corresponds directly to the baud rate being
+represented, however, the following symbolic values are defined.
+.Bd -literal
+#define B0 0
+#define B50 50
+#define B75 75
+#define B110 110
+#define B134 134
+#define B150 150
+#define B200 200
+#define B300 300
+#define B600 600
+#define B1200 1200
+#define B1800 1800
+#define B2400 2400
+#define B4800 4800
+#define B9600 9600
+#define B19200 19200
+#define B38400 38400
+#ifndef _POSIX_SOURCE
+#define EXTA 19200
+#define EXTB 38400
+#endif /*_POSIX_SOURCE */
+.Ed
+.Pp
+The
+.Nm cfgetispeed
+function returns the input baud rate in the termios structure referenced by
+.Fa tp .
+.Pp
+The
+.Nm cfsetispeed
+function sets the input baud rate in the termios structure referenced by
+.Fa tp
+to
+.Fa speed .
+.Pp
+The
+.Nm cfgetospeed
+function returns the output baud rate in the termios structure referenced by
+.Fa tp .
+.Pp
+The
+.Nm cfsetospeed
+function sets the output baud rate in the termios structure referenced by
+.Fa tp
+to
+.Fa speed .
+.Pp
+The
+.Nm cfsetspeed
+function sets both the input and output baud rate in the termios structure
+referenced by
+.Fa tp
+to
+.Fa speed .
+.Pp
+Upon successful completion, the functions
+.Nm cfsetispeed ,
+.Nm cfsetospeed ,
+and
+.Nm cfsetspeed
+return a value of 0.
+Otherwise, a value of -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh GETTING AND SETTING THE TERMIOS STATE
+This section describes the functions that are used to control the general
+terminal interface.
+Unless otherwise noted for a specific command, these functions are restricted
+from use by background processes.
+Attempts to perform these operations shall cause the process group to be sent
+a SIGTTOU signal.
+If the calling process is blocking or ignoring SIGTTOU signals, the process
+is allowed to perform the operation and the SIGTTOU signal is not sent.
+.Pp
+In all the functions, although
+.Fa fd
+is an open file descriptor, the functions affect the underlying terminal
+file, not just the open file description associated with the particular
+file descriptor.
+.Pp
+The
+.Nm cfmakeraw
+function sets the flags stored in the termios structure to a state disabling
+all input and output processing, giving a
+.Dq raw I/O path.
+It should be noted that there is no function to reverse this effect.
+This is because there are a variety of processing options that could be
+re-enabled and the correct method is for an application to snapshot the
+current terminal state using the function
+.Nm tcgetattr ,
+setting raw mode with
+.Nm cfmakeraw
+and the subsequent
+.Nm tcsetattr ,
+and then using another
+.Nm tcsetattr
+with the saved state to revert to the previous terminal state.
+.Pp
+The
+.Nm tcgetattr
+function copies the parameters associated with the terminal referenced
+by
+.Fa fd
+in the termios structure referenced by
+.Fa tp .
+This function is allowed from a background process, however, the terminal
+attributes may be subsequently changed by a foreground process.
+.Pp
+The
+.Nm tcsetattr
+function sets the parameters associated with the terminal from the
+termios structure referenced by
+.Fa tp .
+The
+.Fa action
+field is created by
+.Em or Ns 'ing
+the following values, as specified in the include file
+.Aq Pa termios.h .
+.Bl -tag -width "TCSADRAIN"
+.It Fa TCSANOW
+The change occurs immediately.
+.It Fa TCSADRAIN
+The change occurs after all output written to
+.Fa fd
+has been transmitted to the terminal.
+This value of
+.Fa action
+should be used when changing parameters that affect output.
+.It Fa TCSAFLUSH
+The change occurs after all output written to
+.Fa fd
+has been transmitted to the terminal
+Additionally, any input that has been received but not read is discarded.
+.It Fa TCSASOFT
+If this value is
+.Em or Ns 'ed
+into the
+.Fa action
+value, the values of the
+.Em c_cflag ,
+.Em c_ispeed ,
+and
+.Em c_ospeed
+fields are ignored.
+.El
+.Pp
+The 0 baud rate is used to terminate the connection.
+If 0 is specified as the output speed to the function
+.Nm tcsetattr ,
+modem control will no longer be asserted on the terminal, disconnecting
+the terminal.
+.Pp
+If zero is specified as the input speed to the function
+.Nm tcsetattr ,
+the input baud rate will be set to the same value as that specified by
+the output baud rate.
+.Pp
+If
+.Nm tcsetattr
+is unable able to make any of the requested changes, it returns -1 and
+sets errno.
+Otherwise, it makes all of the requested changes it can.
+If the specified input and output baud rates differ and are a combination
+that is not supported, neither baud rate is changed.
+.Pp
+Upon successful completion, the functions
+.Nm tcgetattr
+and
+.Nm tcsetattr
+return a value of 0.
+Otherwise, they
+return -1 and the global variable
+.Va errno
+is set to indicate the error, as follows:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument to
+.Nm tcgetattr
+or
+.Nm tcsetattr
+was not a valid file descriptor.
+.It Bq Er EINTR
+The
+.Nm tcsetattr
+function was interrupted by a signal.
+.It Bq Er EINVAL
+The
+.Fa action
+argument to the
+.Nm tcsetattr
+function was not valid, or an attempt was made to change an attribute
+represented in the termios structure to an unsupported value.
+.It Bq Er ENOTTY
+The file associated with the
+.Fa fd
+argument to
+.Nm tcgetattr
+or
+.Nm tcsetattr
+is not a terminal.
+.El
+.Sh SEE ALSO
+.Xr tcsendbreak 3 ,
+.Xr termios 4
+.Sh STANDARDS
+The
+.Nm cfgetispeed ,
+.Nm cfsetispeed ,
+.Nm cfgetospeed ,
+.Nm cfsetospeed ,
+.Nm tcgetattr
+and
+.Nm tcsetattr
+functions are expected to be compliant with the
+.St -p1003.1-88
+specification.
+The
+.Nm cfmakeraw
+and
+.Nm cfsetspeed
+functions,
+as well as the
+.Li TCSASOFT
+option to the
+.Nm tcsetattr
+function are extensions to the
+.St -p1003.1-88
+specification.
diff --git a/lib/libc/gen/tcsetpgrp.3 b/lib/libc/gen/tcsetpgrp.3
new file mode 100644
index 000000000000..ff881cb437d8
--- /dev/null
+++ b/lib/libc/gen/tcsetpgrp.3
@@ -0,0 +1,100 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcsetpgrp.3 5.3 (Berkeley) 3/29/92
+.\"
+.Dd "March 29, 1992"
+.Dt TCSETPGRP
+.Os
+.Sh NAME
+.Nm tcsetpgrp
+.Nd set foreground process group ID
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <unistd.h>
+.Ft int
+.Fn tcsetpgrp "int fd" "pid_t pgrp_id"
+.Sh DESCRIPTION
+If the process has a controlling terminal, the
+.Nm tcsetpgrp
+function sets the foreground process group ID associated with the
+terminal device to
+.Fa pgrp_id .
+The terminal device associated with
+.Fa fd
+must be the controlling terminal of the calling process and the
+controlling terminal must be currently associated with the session
+of the calling process.
+The value of
+.Fa pgrp_id
+must be the same as the process group ID of a process in the same
+session as the calling process.
+.Pp
+Upon successful completion,
+.Nm tcsetpgrp
+returns a value of zero.
+.Sh ERRORS
+If an error occurs,
+.Nm tcgetpgrp
+returns -1 and the global variable
+.Va errno
+is set to indicate the error, as follows:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid file descriptor.
+.It Bq Er EINVAL
+An invalid value of
+.Fa pgrp_id
+was specified.
+.It Bq Er ENOTTY
+The calling process does not have a controlling terminal, or the file
+represented by
+.Fa fd
+is not the controlling terminal, or the controlling terminal is no
+longer associated with the session of the calling process.
+.It Bq Er EPERM
+The
+.Fa pgrp_id
+argument does not match the process group ID of a process in the same
+session as the calling process.
+.El
+.Sh SEE ALSO
+.Xr setpgid 3 ,
+.Xr setsid 2 ,
+.Xr tcgetpgrp 3
+.Sh STANDARDS
+The
+.Nm tcsetpgprp
+function is expected to be compliant with the
+.St -p1003.1-88
+specification.
diff --git a/lib/libc/gen/timezone.3 b/lib/libc/gen/timezone.3
index bfd460eda664..bafa0154427e 100644
--- a/lib/libc/gen/timezone.3
+++ b/lib/libc/gen/timezone.3
@@ -49,7 +49,7 @@ See ctime(3).
.Pp
The
.Fn timezone
-function returns a pointer to a time zone abbreviation for the specifed
+function returns a pointer to a time zone abbreviation for the specified
.Ar zone
and
.Ar dst
diff --git a/lib/libc/gen/timezone.c b/lib/libc/gen/timezone.c
index de12f8ff9e5c..9339d5e151a2 100644
--- a/lib/libc/gen/timezone.c
+++ b/lib/libc/gen/timezone.c
@@ -84,6 +84,7 @@ static struct zone {
} zonetab[] = {
-1*60, "MET", "MET DST", /* Middle European */
-2*60, "EET", "EET DST", /* Eastern European */
+ -3*60, "MSK", "MSD", /* Moscow */
4*60, "AST", "ADT", /* Atlantic */
5*60, "EST", "EDT", /* Eastern */
6*60, "CST", "CDT", /* Central */
diff --git a/lib/libc/gen/ualarm.3 b/lib/libc/gen/ualarm.3
index 19fd216fd8b5..dbdc1344a82f 100644
--- a/lib/libc/gen/ualarm.3
+++ b/lib/libc/gen/ualarm.3
@@ -70,7 +70,7 @@ microseconds have passed).
When the signal has successfully been caught,
.Fn alarm
returns the amount of time left on the clock.
-The maximum mumber of
+The maximum number of
.Ar microseconds
allowed
is 2147483647.