loksh-noxz

[fork] a Linux port of OpenBSD's ksh
git clone git://git.noxz.tech/loksh-noxz
Log | Files | Refs | Submodules | README

commit fccb6733b45f73f7006f2870f1789717463ff3d7
parent f1e00bfda58adf6dadbce7a8195090e89162762c
Author: Chris Noxz <chris@noxz.tech>
Date:   Tue,  9 Mar 2021 20:24:15 +0100

Update to use dimkr's lolibc together with meson/ninja

Diffstat:
M.gitignore | 3+--
A.gitmodules | 3+++
ADockerfile | 3+++
DMakefile | 42------------------------------------------
MREADME.md | 19+++++++++++++++++--
Mc_sh.c | 1-
Mc_ulimit.c | 1-
Dcharclass.h | 29-----------------------------
Mci.sh | 22+++++++++++++++-------
Medit.c | 1-
Mhistory.c | 7+------
Mio.c | 2+-
Mjobs.c | 5-----
Mlex.h | 2--
Mmain.c | 18++++++++++++++----
Ameson.build | 32++++++++++++++++++++++++++++++++
Mmisc.c | 7++++---
Dreallocarray.c | 38--------------------------------------
Msh.h | 2--
Dstdlib.h | 45---------------------------------------------
Dstring.h | 45---------------------------------------------
Dstrlcat.c | 55-------------------------------------------------------
Dstrlcpy.c | 50--------------------------------------------------
Dstrtonum.c | 65-----------------------------------------------------------------
Asubprojects/lolibc | 1+
Dsys/queue.h | 534-------------------------------------------------------------------------------
Dsys/time.h | 79-------------------------------------------------------------------------------
Mtable.h | 2--
Mtrap.c | 51++++++++++++++++-----------------------------------
Dunvis.c | 285-------------------------------------------------------------------------------
Mvar.c | 2+-
Mvi.c | 1+
Dvis.c | 241-------------------------------------------------------------------------------
Dvis.h | 88-------------------------------------------------------------------------------
34 files changed, 110 insertions(+), 1671 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1 @@ -ksh -*.o +build diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "subprojects/lolibc"] + path = subprojects/lolibc + url = https://github.com/dimkr/lolibc diff --git a/Dockerfile b/Dockerfile @@ -0,0 +1,3 @@ +FROM dimkr/c-dev:clang + +RUN apt-get -y --no-install-recommends install pkg-config libncurses5-dev diff --git a/Makefile b/Makefile @@ -1,42 +0,0 @@ -CC ?= cc -CFLAGS ?= -O2 -override CFLAGS += -isystem . -D_GNU_SOURCE -DEMACS -DVI -std=gnu99 -Wall -Wno-format-security -Wno-pointer-sign -LDFLAGS ?= -DESTDIR ?= / -PREFIX ?= /usr -BIN_DIR ?= $(PREFIX)/bin -BIN_NAME ?= ksh -MAN_DIR ?= $(PREFIX)/share/man -DOC_DIR ?= $(PREFIX)/share/doc/loksh - -NCURSES_CFLAGS = $(shell pkg-config --cflags ncursesw) -NCURSES_LDFLAGS = $(shell pkg-config --libs ncursesw) - - -OBJECTS = alloc.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o emacs.o eval.o \ - exec.o expr.o history.o io.o jobs.o lex.o mail.o main.o misc.o \ - path.o shf.o syn.o table.o trap.o tree.o tty.o var.o version.o vi.o \ - vis.o unvis.o strlcpy.o strlcat.o reallocarray.o strtonum.o -HEADERS = c_test.h charclass.h config.h edit.h expand.h ksh_limval.h lex.h \ - proto.h sh.h shf.h table.h tree.h tty.h - -all: ksh - -%.o: %.c $(HEADERS) - $(CC) -c -o $@ $< $(CFLAGS) $(NCURSES_CFLAGS) - -ksh: $(OBJECTS) - $(CC) -o $@ $^ $(LDFLAGS) $(NCURSES_LDFLAGS) - -clean: - rm -f $(BIN_NAME) *.o - -install: all - install -v -D -m 755 ksh $(DESTDIR)/$(BIN_DIR)/$(BIN_NAME) - install -v -D -m 644 ksh.1 $(DESTDIR)/$(MAN_DIR)/man1/$(BIN_NAME).1 - install -v -m 644 sh.1 $(DESTDIR)/$(MAN_DIR)/man1/sh.1 - install -v -D -m 644 README.md $(DESTDIR)/$(DOC_DIR)/README.md - install -v -m 644 README $(DESTDIR)/$(DOC_DIR)/README - install -v -m 644 CONTRIBUTORS $(DESTDIR)/$(DOC_DIR)/CONTRIBUTORS - install -v -m 644 PROJECTS $(DESTDIR)/$(DOC_DIR)/PROJETCS - install -v -m 644 LEGAL $(DESTDIR)/$(DOC_DIR)/LEGAL diff --git a/README.md b/README.md @@ -6,13 +6,28 @@ |_|\___/|_|\_\___/_| |_| ``` -[![Build Status](https://travis-ci.org/dimkr/loksh.svg?branch=master)](https://travis-ci.org/dimkr/loksh) +[![Build Status](https://github.com/dimkr/loksh/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/dimkr/loksh/actions) ## Overview loksh is a [Linux](https://www.kernel.org/) port of [OpenBSD](http://www.openbsd.org/)'s *ksh*. -Unlike other ports of *ksh*, loksh targets only one platform, follows upstream closely and keeps changes to a minimum. loksh does not add any extra features; this reduces the risk of introducing security vulnerabilities and makes loksh a good fit for resource-constrained systems. +Unlike other ports of *ksh*, loksh targets only one platform, follows upstream closely and [keeps changes to a minimum](https://github.com/dimkr/loksh/compare/upstream%2Fmaster...master). loksh does not add any extra features; this reduces the risk of introducing security vulnerabilities and makes loksh a good fit for resource-constrained systems. + +## Installation + +loksh is included in many distributions: + +[![Packaging status](https://repology.org/badge/vertical-allrepos/loksh.svg?minversion=6.7.5&header=)](https://repology.org/project/loksh/versions) + +For example, under [Alpine Linux](https://alpinelinux.org/), loksh can be installed using `apk add loksh`. + +Alternatively, to build and install loksh from source: + +```bash +meson --prefix=/usr build +ninja -C build install +``` ## Legal Information diff --git a/c_sh.c b/c_sh.c @@ -4,7 +4,6 @@ * built-in Bourne commands */ -#include <sys/types.h> #include <sys/resource.h> #include <sys/stat.h> #include <sys/time.h> diff --git a/c_ulimit.c b/c_ulimit.c @@ -18,7 +18,6 @@ that was originally under case SYSULIMIT in source file "xec.c". */ -#include <sys/types.h> #include <sys/resource.h> #include <ctype.h> diff --git a/charclass.h b/charclass.h @@ -1,29 +0,0 @@ -/* - * Public domain, 2008, Todd C. Miller <millert@openbsd.org> - * - * $OpenBSD: charclass.h,v 1.2 2019/01/25 00:19:25 millert Exp $ - */ - -/* - * POSIX character class support for fnmatch() and glob(). - */ -static struct cclass { - const char *name; - int (*isctype)(int); -} cclasses[] = { - { "alnum", isalnum }, - { "alpha", isalpha }, - { "blank", isblank }, - { "cntrl", iscntrl }, - { "digit", isdigit }, - { "graph", isgraph }, - { "lower", islower }, - { "print", isprint }, - { "punct", ispunct }, - { "space", isspace }, - { "upper", isupper }, - { "xdigit", isxdigit }, - { NULL, NULL } -}; - -#define NCCLASSES (sizeof(cclasses) / sizeof(cclasses[0]) - 1) diff --git a/ci.sh b/ci.sh @@ -1,16 +1,24 @@ #!/bin/sh -xe -jobs=`nproc` -make -j$jobs -make DESTDIR=dst install +meson --buildtype=release --prefix=/usr build +DESTDIR=../dst ninja -C build install +./dst/usr/bin/ksh -c "kill -l" +[ "`echo 'kill -l 9' | ./dst/usr/bin/ksh`" != KILL ] && exit 1 +[ -n "`./dst/usr/bin/ksh -c 'echo &' 2>&1 | grep 'internal error'`" ] && exit 1 [ "`./dst/usr/bin/ksh -c 'echo $((1337 * 2))'`" -ne 2674 ] && exit 1 [ "`./dst/usr/bin/ksh -c 'seq 1337 | sort -rn | head -n 1'`" -ne 1337 ] && exit 1 -make clean -CC=clang make -j$jobs +CC=clang meson --buildtype=release build-clang +ninja -C build-clang if [ "`readlink /proc/$$/exe`" != /tmp/ksh ] then - cp -f ksh /tmp/ - make clean + cp -f dst/usr/bin/ksh /tmp/ + rm -rf build build-clang dst exec /tmp/ksh -xe $0 fi + +for i in arm-any32-linux-musleabi mips-any32-linux-musl +do + meson --buildtype=release --cross-file=$i build-$i + ninja -C build-$i +done diff --git a/edit.c b/edit.c @@ -9,7 +9,6 @@ #include <sys/ioctl.h> #include <sys/stat.h> -#include <sys/types.h> #include <ctype.h> #include <errno.h> diff --git a/history.c b/history.c @@ -12,11 +12,7 @@ * things. */ -#include <sys/types.h> #include <sys/stat.h> -#include <sys/time.h> -#include <sys/uio.h> -#include <sys/file.h> #include <errno.h> #include <fcntl.h> @@ -25,7 +21,6 @@ #include <string.h> #include <unistd.h> #include <vis.h> -#include <inttypes.h> #include "sh.h" @@ -729,7 +724,7 @@ history_open(void) struct stat sb; int fd, fddup; - if ((fd = open(hname, O_RDWR | O_CREAT, 0600)) == -1) + if ((fd = open(hname, O_RDWR | O_CREAT | O_EXLOCK, 0600)) == -1) return NULL; if (fstat(fd, &sb) == -1 || sb.st_uid != getuid()) { close(fd); diff --git a/io.c b/io.c @@ -109,7 +109,7 @@ internal_warningf(const char *fmt, ...) } /* Warn and unwind when something that shouldn't happen does */ -__attribute__((__noreturn__)) void +__dead void internal_errorf(const char *fmt, ...) { va_list va; diff --git a/jobs.c b/jobs.c @@ -15,7 +15,6 @@ * */ -#include <sys/types.h> #include <sys/resource.h> #include <sys/stat.h> #include <sys/time.h> @@ -150,11 +149,7 @@ static int kill_job(Job *, int); void j_init(int mflagset) { -#ifdef CHILD_MAX child_max = CHILD_MAX; /* so syscon() isn't always being called */ -#else - child_max = sysconf(_SC_CHILD_MAX); -#endif sigemptyset(&sm_default); sigprocmask(SIG_SETMASK, &sm_default, NULL); diff --git a/lex.h b/lex.h @@ -6,8 +6,6 @@ /* $From: lex.h,v 1.4 1994/05/31 13:34:34 michael Exp $ */ -#include <inttypes.h> - #define IDENT 64 typedef struct source Source; diff --git a/main.c b/main.c @@ -17,10 +17,6 @@ #include "sh.h" -#ifndef _PW_NAME_LEN -# define _PW_NAME_LEN 32 /* see the useradd(8) man page */ -#endif - extern char **environ; /* @@ -150,6 +146,20 @@ main(int argc, char *argv[]) kshname = argv[0]; + if (issetugid()) { /* could later drop privileges */ + if (pledge("stdio rpath wpath cpath fattr flock getpw proc " + "exec tty id", NULL) == -1) { + perror("pledge"); + exit(1); + } + } else { + if (pledge("stdio rpath wpath cpath fattr flock getpw proc " + "exec tty", NULL) == -1) { + perror("pledge"); + exit(1); + } + } + ainit(&aperm); /* initialize permanent Area */ /* set up base environment */ diff --git a/meson.build b/meson.build @@ -0,0 +1,32 @@ +project('loksh', 'c', version: '6.8') + +lolibc = subproject('lolibc') + +c_args = ['-D_GNU_SOURCE', '-DEMACS', '-DVI', '-Wno-format-security', '-Wno-pointer-sign'] +deps = [] + +ncurses = dependency('ncurses', required: false) +if ncurses.found() + deps += [ncurses] +else + c_args += ['-DSMALL'] +endif + +ksh = executable('ksh', + 'alloc.c', 'c_ksh.c', 'c_sh.c', 'c_test.c', 'c_ulimit.c', 'edit.c', 'emacs.c', 'eval.c', + 'exec.c', 'expr.c', 'history.c', 'io.c', 'jobs.c', 'lex.c', 'mail.c', 'main.c', 'misc.c', + 'path.c', 'shf.c', 'syn.c', 'table.c', 'trap.c', 'tree.c', 'tty.c', 'var.c', 'version.c', 'vi.c', + c_args: c_args + lolibc.get_variable('lolibc_c_args'), + include_directories: lolibc.get_variable('lolibc_includes'), + dependencies: deps, + link_with: lolibc.get_variable('liblolibc'), + install: true) + +install_man('ksh.1', 'sh.1') + +install_data('README.md', + 'README', + 'CONTRIBUTORS', + 'PROJECTS', + 'LEGAL', + install_dir: join_paths(get_option('datadir'), 'doc', 'loksh')) diff --git a/misc.c b/misc.c @@ -11,8 +11,6 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <grp.h> -#include <sys/auxv.h> #include "sh.h" #include "charclass.h" @@ -294,7 +292,7 @@ change_flag(enum sh_flag f, } } else /* Turning off -p? */ - if (f == FPRIVILEGED && oldval && !newval && getauxval(AT_SECURE) && + if (f == FPRIVILEGED && oldval && !newval && issetugid() && !dropped_privileges) { gid_t gid = getgid(); @@ -302,6 +300,9 @@ change_flag(enum sh_flag f, setgroups(1, &gid); setresuid(ksheuid, ksheuid, ksheuid); + if (pledge("stdio rpath wpath cpath fattr flock getpw proc " + "exec tty", NULL) == -1) + bi_errorf("pledge fail"); dropped_privileges = 1; } else if (f == FPOSIX && newval) { Flag(FBRACEEXPAND) = 0; diff --git a/reallocarray.c b/reallocarray.c @@ -1,38 +0,0 @@ -/* $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $ */ -/* - * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/types.h> -#include <errno.h> -#include <stdint.h> -#include <stdlib.h> - -/* - * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX - * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW - */ -#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) - -void * -reallocarray(void *optr, size_t nmemb, size_t size) -{ - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) { - errno = ENOMEM; - return NULL; - } - return realloc(optr, size * nmemb); -} diff --git a/sh.h b/sh.h @@ -15,9 +15,7 @@ #include <stdarg.h> #include <stddef.h> #include <signal.h> -#include <time.h> #include <stdbool.h> -#include <fcntl.h> /* end of common headers */ diff --git a/stdlib.h b/stdlib.h @@ -1,45 +0,0 @@ -#ifndef _COMPAT_STDLIB_H_ -#define _COMPAT_STDLIB_H_ - -#include_next <stdlib.h> - -/* $OpenBSD: stdlib.h,v 1.76 2019/05/10 15:03:24 otto Exp $ */ -/* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */ - -/*- - * Copyright (c) 1990 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. 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. - * - * @(#)stdlib.h 5.13 (Berkeley) 6/4/91 - */ - -void *reallocarray(void *, size_t, size_t); - -long long - strtonum(const char *, long long, long long, const char **); - -#endif diff --git a/string.h b/string.h @@ -1,45 +0,0 @@ -#ifndef _COMPAT_STRING_H_ -#define _COMPAT_STRING_H_ - -#include_next <string.h> - -/* $OpenBSD: string.h,v 1.32 2017/09/05 03:16:13 schwarze Exp $ */ -/* $NetBSD: string.h,v 1.6 1994/10/26 00:56:30 cgd Exp $ */ - -/*- - * Copyright (c) 1990 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. 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. - * - * @(#)string.h 5.10 (Berkeley) 3/9/91 - */ - -size_t strlcat(char *, const char *, size_t) - __attribute__ ((__bounded__(__string__,1,3))); -size_t strlcpy(char *, const char *, size_t) - __attribute__ ((__bounded__(__string__,1,3))); - -#endif diff --git a/strlcat.c b/strlcat.c @@ -1,55 +0,0 @@ -/* $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $ */ - -/* - * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/types.h> -#include <string.h> - -/* - * Appends src to string dst of size dsize (unlike strncat, dsize is the - * full size of dst, not space left). At most dsize-1 characters - * will be copied. Always NUL terminates (unless dsize <= strlen(dst)). - * Returns strlen(src) + MIN(dsize, strlen(initial dst)). - * If retval >= dsize, truncation occurred. - */ -size_t -strlcat(char *dst, const char *src, size_t dsize) -{ - const char *odst = dst; - const char *osrc = src; - size_t n = dsize; - size_t dlen; - - /* Find the end of dst and adjust bytes left but don't go past end. */ - while (n-- != 0 && *dst != '\0') - dst++; - dlen = dst - odst; - n = dsize - dlen; - - if (n-- == 0) - return(dlen + strlen(src)); - while (*src != '\0') { - if (n != 0) { - *dst++ = *src; - n--; - } - src++; - } - *dst = '\0'; - - return(dlen + (src - osrc)); /* count does not include NUL */ -} diff --git a/strlcpy.c b/strlcpy.c @@ -1,50 +0,0 @@ -/* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */ - -/* - * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/types.h> -#include <string.h> - -/* - * Copy string src to buffer dst of size dsize. At most dsize-1 - * chars will be copied. Always NUL terminates (unless dsize == 0). - * Returns strlen(src); if retval >= dsize, truncation occurred. - */ -size_t -strlcpy(char *dst, const char *src, size_t dsize) -{ - const char *osrc = src; - size_t nleft = dsize; - - /* Copy as many bytes as will fit. */ - if (nleft != 0) { - while (--nleft != 0) { - if ((*dst++ = *src++) == '\0') - break; - } - } - - /* Not enough room in dst, add NUL and traverse rest of src. */ - if (nleft == 0) { - if (dsize != 0) - *dst = '\0'; /* NUL-terminate dst */ - while (*src++) - ; - } - - return(src - osrc - 1); /* count does not include NUL */ -} diff --git a/strtonum.c b/strtonum.c @@ -1,65 +0,0 @@ -/* $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */ - -/* - * Copyright (c) 2004 Ted Unangst and Todd Miller - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <errno.h> -#include <limits.h> -#include <stdlib.h> - -#define INVALID 1 -#define TOOSMALL 2 -#define TOOLARGE 3 - -long long -strtonum(const char *numstr, long long minval, long long maxval, - const char **errstrp) -{ - long long ll = 0; - int error = 0; - char *ep; - struct errval { - const char *errstr; - int err; - } ev[4] = { - { NULL, 0 }, - { "invalid", EINVAL }, - { "too small", ERANGE }, - { "too large", ERANGE }, - }; - - ev[0].err = errno; - errno = 0; - if (minval > maxval) { - error = INVALID; - } else { - ll = strtoll(numstr, &ep, 10); - if (numstr == ep || *ep != '\0') - error = INVALID; - else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) - error = TOOSMALL; - else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) - error = TOOLARGE; - } - if (errstrp != NULL) - *errstrp = ev[error].errstr; - errno = ev[error].err; - if (error) - ll = 0; - - return (ll); -} diff --git a/subprojects/lolibc b/subprojects/lolibc @@ -0,0 +1 @@ +Subproject commit 801784932948e693c9cf172bec73fd26a244e3d0 diff --git a/sys/queue.h b/sys/queue.h @@ -1,534 +0,0 @@ -/* $OpenBSD: queue.h,v 1.45 2018/07/12 14:22:54 sashan Exp $ */ -/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ - -/* - * Copyright (c) 1991, 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 - * 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. 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. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines five types of data structures: singly-linked lists, - * lists, simple queues, tail queues and XOR simple queues. - * - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * An XOR simple queue is used in the same way as a regular simple queue. - * The difference is that the head structure also includes a "cookie" that - * is XOR'd with the queue pointer (first, last or next) to generate the - * real pointer value. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) -#define _Q_INVALID ((void *)-1) -#define _Q_INVALIDATE(a) (a) = _Q_INVALID -#else -#define _Q_INVALIDATE(a) -#endif - -/* - * Singly-linked List definitions. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List access methods. - */ -#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_END(head) NULL -#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_FOREACH(var, head, field) \ - for((var) = SLIST_FIRST(head); \ - (var) != SLIST_END(head); \ - (var) = SLIST_NEXT(var, field)) - -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST(head); \ - (var) && ((tvar) = SLIST_NEXT(var, field), 1); \ - (var) = (tvar)) - -/* - * Singly-linked List functions. - */ -#define SLIST_INIT(head) { \ - SLIST_FIRST(head) = SLIST_END(head); \ -} - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (0) - -#define SLIST_REMOVE_AFTER(elm, field) do { \ - (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if ((head)->slh_first == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->slh_first; \ - \ - while (curelm->field.sle_next != (elm)) \ - curelm = curelm->field.sle_next; \ - curelm->field.sle_next = \ - curelm->field.sle_next->field.sle_next; \ - } \ - _Q_INVALIDATE((elm)->field.sle_next); \ -} while (0) - -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List access methods. - */ -#define LIST_FIRST(head) ((head)->lh_first) -#define LIST_END(head) NULL -#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_FOREACH(var, head, field) \ - for((var) = LIST_FIRST(head); \ - (var)!= LIST_END(head); \ - (var) = LIST_NEXT(var, field)) - -#define LIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = LIST_FIRST(head); \ - (var) && ((tvar) = LIST_NEXT(var, field), 1); \ - (var) = (tvar)) - -/* - * List functions. - */ -#define LIST_INIT(head) do { \ - LIST_FIRST(head) = LIST_END(head); \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (0) - -#define LIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ - _Q_INVALIDATE((elm)->field.le_prev); \ - _Q_INVALIDATE((elm)->field.le_next); \ -} while (0) - -#define LIST_REPLACE(elm, elm2, field) do { \ - if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ - (elm2)->field.le_next->field.le_prev = \ - &(elm2)->field.le_next; \ - (elm2)->field.le_prev = (elm)->field.le_prev; \ - *(elm2)->field.le_prev = (elm2); \ - _Q_INVALIDATE((elm)->field.le_prev); \ - _Q_INVALIDATE((elm)->field.le_next); \ -} while (0) - -/* - * Simple queue definitions. - */ -#define SIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define SIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define SIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue access methods. - */ -#define SIMPLEQ_FIRST(head) ((head)->sqh_first) -#define SIMPLEQ_END(head) NULL -#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) -#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - -#define SIMPLEQ_FOREACH(var, head, field) \ - for((var) = SIMPLEQ_FIRST(head); \ - (var) != SIMPLEQ_END(head); \ - (var) = SIMPLEQ_NEXT(var, field)) - -#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SIMPLEQ_FIRST(head); \ - (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \ - (var) = (tvar)) - -/* - * Simple queue functions. - */ -#define SIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (0) - -#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (0) - -#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (0) - -#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ - if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \ - == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (0) - -#define SIMPLEQ_CONCAT(head1, head2) do { \ - if (!SIMPLEQ_EMPTY((head2))) { \ - *(head1)->sqh_last = (head2)->sqh_first; \ - (head1)->sqh_last = (head2)->sqh_last; \ - SIMPLEQ_INIT((head2)); \ - } \ -} while (0) - -/* - * XOR Simple queue definitions. - */ -#define XSIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqx_first; /* first element */ \ - struct type **sqx_last; /* addr of last next element */ \ - unsigned long sqx_cookie; \ -} - -#define XSIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqx_next; /* next element */ \ -} - -/* - * XOR Simple queue access methods. - */ -#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \ - (unsigned long)(ptr))) -#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first)) -#define XSIMPLEQ_END(head) NULL -#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head)) -#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next)) - - -#define XSIMPLEQ_FOREACH(var, head, field) \ - for ((var) = XSIMPLEQ_FIRST(head); \ - (var) != XSIMPLEQ_END(head); \ - (var) = XSIMPLEQ_NEXT(head, var, field)) - -#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = XSIMPLEQ_FIRST(head); \ - (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \ - (var) = (tvar)) - -/* - * XOR Simple queue functions. - */ -#define XSIMPLEQ_INIT(head) do { \ - arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \ - (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \ - (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \ -} while (0) - -#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqx_next = (head)->sqx_first) == \ - XSIMPLEQ_XOR(head, NULL)) \ - (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ - (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \ -} while (0) - -#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \ - *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \ - (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ -} while (0) - -#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \ - XSIMPLEQ_XOR(head, NULL)) \ - (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ - (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \ -} while (0) - -#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqx_first = XSIMPLEQ_XOR(head, \ - (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \ - (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \ -} while (0) - -#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \ - if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \ - (elm)->field.sqx_next)->field.sqx_next) \ - == XSIMPLEQ_XOR(head, NULL)) \ - (head)->sqx_last = \ - XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ -} while (0) - - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * Tail queue access methods. - */ -#define TAILQ_FIRST(head) ((head)->tqh_first) -#define TAILQ_END(head) NULL -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -/* XXX */ -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) -#define TAILQ_EMPTY(head) \ - (TAILQ_FIRST(head) == TAILQ_END(head)) - -#define TAILQ_FOREACH(var, head, field) \ - for((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT(var, field)) - -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head) && \ - ((tvar) = TAILQ_NEXT(var, field), 1); \ - (var) = (tvar)) - - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for((var) = TAILQ_LAST(head, headname); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_PREV(var, headname, field)) - -#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ - for ((var) = TAILQ_LAST(head, headname); \ - (var) != TAILQ_END(head) && \ - ((tvar) = TAILQ_PREV(var, headname, field), 1); \ - (var) = (tvar)) - -/* - * Tail queue functions. - */ -#define TAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ - _Q_INVALIDATE((elm)->field.tqe_prev); \ - _Q_INVALIDATE((elm)->field.tqe_next); \ -} while (0) - -#define TAILQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ - (elm2)->field.tqe_next->field.tqe_prev = \ - &(elm2)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm2)->field.tqe_next; \ - (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ - *(elm2)->field.tqe_prev = (elm2); \ - _Q_INVALIDATE((elm)->field.tqe_prev); \ - _Q_INVALIDATE((elm)->field.tqe_next); \ -} while (0) - -#define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - *(head1)->tqh_last = (head2)->tqh_first; \ - (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_INIT((head2)); \ - } \ -} while (0) - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/sys/time.h b/sys/time.h @@ -1,79 +0,0 @@ -/* $OpenBSD: time.h,v 1.46 2019/08/03 22:53:45 cheloha Exp $ */ -/* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */ - -/* - * Copyright (c) 1982, 1986, 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 - * 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. 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. - * - * @(#)time.h 8.2 (Berkeley) 7/10/94 - */ - -#ifndef _SYS_TIME_H_ -#define _SYS_TIME_H_ - -/* Operations on timevals. */ -#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 -#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) -#define timercmp(tvp, uvp, cmp) \ - (((tvp)->tv_sec == (uvp)->tv_sec) ? \ - ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ - ((tvp)->tv_sec cmp (uvp)->tv_sec)) -#define timeradd(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ - if ((vvp)->tv_usec >= 1000000) { \ - (vvp)->tv_sec++; \ - (vvp)->tv_usec -= 1000000; \ - } \ - } while (0) -#define timersub(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ - if ((vvp)->tv_usec < 0) { \ - (vvp)->tv_sec--; \ - (vvp)->tv_usec += 1000000; \ - } \ - } while (0) - -/* Operations on timespecs. */ -#define timespeccmp(tsp, usp, cmp) \ - (((tsp)->tv_sec == (usp)->tv_sec) ? \ - ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ - ((tsp)->tv_sec cmp (usp)->tv_sec)) -#define timespecsub(tsp, usp, vsp) \ - do { \ - (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ - (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ - if ((vsp)->tv_nsec < 0) { \ - (vsp)->tv_sec--; \ - (vsp)->tv_nsec += 1000000000L; \ - } \ - } while (0) - -#endif /* !_SYS_TIME_H_ */ diff --git a/table.h b/table.h @@ -2,8 +2,6 @@ /* $From: table.h,v 1.3 1994/05/31 13:34:34 michael Exp $ */ -#include <inttypes.h> - /* * generic hashed associative table for commands and variables. */ diff --git a/trap.c b/trap.c @@ -11,47 +11,28 @@ #include "sh.h" -Trap sigtraps[NSIG + 1] = { - { SIGEXIT_, "EXIT", "Signal 0" }, - { 1 , "HUP", "Hangup" }, - { 2 , "INT", "Interrupt" }, - { 3 , "QUIT", "Quit" }, - { 4 , "ILL", "Illegal instruction" }, - { 5 , "TRAP", "Trace trap" }, - { 6 , "ABRT", "Abort" }, - { 7 , "BUS", "Bus error" }, - { 8 , "FPE", "Floating point exception" }, - { 9 , "KILL", "Killed" }, - { 10 , "USR1", "User defined signal 1" }, - { 11 , "SEGV", "Memory fault" }, - { 12 , "USR2", "User defined signal 2" }, - { 13 , "PIPE", "Broken pipe" }, - { 14 , "ALRM", "Alarm clock" }, - { 15 , "TERM", "Terminated" }, - { 16 , "STKFLT", "Stack fault" }, - { 17 , "CHLD", "Child exited" }, - { 18 , "CONT", "Continued" }, - { 19 , "STOP", "Stopped (signal)" }, - { 20 , "TSTP", "Stopped" }, - { 21 , "TTIN", "Stopped (tty input)" }, - { 22 , "TTOU", "Stopped (tty output)" }, - { 23 , "URG", "Urgent I/O condition" }, - { 24 , "XCPU", "CPU time limit exceeded" }, - { 25 , "XFSZ", "File size limit exceeded" }, - { 26 , "VTALRM", "Virtual timer expired" }, - { 27 , "PROF", "Profiling timer expired" }, - { 28 , "WINCH", "Window size change" }, - { 29 , "IO", "I/O possible" }, - { 30 , "PWR", "Power-fail/Restart" }, - { 31 , "UNUSED", "Unused" }, - { SIGERR_, "ERR", "Error handler" } -}; +Trap sigtraps[NSIG + 1]; static struct sigaction Sigact_ign, Sigact_trap; void inittraps(void) { + int i; + + /* Populate sigtraps based on sys_signame and sys_siglist. */ + for (i = 0; i <= NSIG; i++) { + sigtraps[i].signal = i; + if (i == SIGERR_) { + sigtraps[i].name = "ERR"; + sigtraps[i].mess = "Error handler"; + } else { + sigtraps[i].name = sys_signame[i]; + sigtraps[i].mess = sys_siglist[i]; + } + } + sigtraps[SIGEXIT_].name = "EXIT"; /* our name for signal 0 */ + sigemptyset(&Sigact_ign.sa_mask); Sigact_ign.sa_flags = 0; /* interruptible */ Sigact_ign.sa_handler = SIG_IGN; diff --git a/unvis.c b/unvis.c @@ -1,285 +0,0 @@ -/* $OpenBSD: unvis.c,v 1.17 2015/09/13 11:32:51 guenther Exp $ */ -/*- - * Copyright (c) 1989, 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 - * 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. 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. - */ - -#include <sys/types.h> -#include <ctype.h> -#include <vis.h> - -/* - * decode driven by state machine - */ -#define S_GROUND 0 /* haven't seen escape char */ -#define S_START 1 /* start decoding special sequence */ -#define S_META 2 /* metachar started (M) */ -#define S_META1 3 /* metachar more, regular char (-) */ -#define S_CTRL 4 /* control char started (^) */ -#define S_OCTAL2 5 /* octal digit 2 */ -#define S_OCTAL3 6 /* octal digit 3 */ - -#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') - -/* - * unvis - decode characters previously encoded by vis - */ -int -unvis(char *cp, char c, int *astate, int flag) -{ - - if (flag & UNVIS_END) { - if (*astate == S_OCTAL2 || *astate == S_OCTAL3) { - *astate = S_GROUND; - return (UNVIS_VALID); - } - return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); - } - - switch (*astate) { - - case S_GROUND: - *cp = 0; - if (c == '\\') { - *astate = S_START; - return (0); - } - *cp = c; - return (UNVIS_VALID); - - case S_START: - switch(c) { - case '-': - *cp = 0; - *astate = S_GROUND; - return (0); - case '\\': - case '"': - *cp = c; - *astate = S_GROUND; - return (UNVIS_VALID); - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - *cp = (c - '0'); - *astate = S_OCTAL2; - return (0); - case 'M': - *cp = (char) 0200; - *astate = S_META; - return (0); - case '^': - *astate = S_CTRL; - return (0); - case 'n': - *cp = '\n'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'r': - *cp = '\r'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'b': - *cp = '\b'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'a': - *cp = '\007'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'v': - *cp = '\v'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 't': - *cp = '\t'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'f': - *cp = '\f'; - *astate = S_GROUND; - return (UNVIS_VALID); - case 's': - *cp = ' '; - *astate = S_GROUND; - return (UNVIS_VALID); - case 'E': - *cp = '\033'; - *astate = S_GROUND; - return (UNVIS_VALID); - case '\n': - /* - * hidden newline - */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); - case '$': - /* - * hidden marker - */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); - } - *astate = S_GROUND; - return (UNVIS_SYNBAD); - - case S_META: - if (c == '-') - *astate = S_META1; - else if (c == '^') - *astate = S_CTRL; - else { - *astate = S_GROUND; - return (UNVIS_SYNBAD); - } - return (0); - - case S_META1: - *astate = S_GROUND; - *cp |= c; - return (UNVIS_VALID); - - case S_CTRL: - if (c == '?') - *cp |= 0177; - else - *cp |= c & 037; - *astate = S_GROUND; - return (UNVIS_VALID); - - case S_OCTAL2: /* second possible octal digit */ - if (isoctal(c)) { - /* - * yes - and maybe a third - */ - *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; - return (0); - } - /* - * no - done with current sequence, push back passed char - */ - *astate = S_GROUND; - return (UNVIS_VALIDPUSH); - - case S_OCTAL3: /* third possible octal digit */ - *astate = S_GROUND; - if (isoctal(c)) { - *cp = (*cp << 3) + (c - '0'); - return (UNVIS_VALID); - } - /* - * we were done, push back passed char - */ - return (UNVIS_VALIDPUSH); - - default: - /* - * decoder in unknown state - (probably uninitialized) - */ - *astate = S_GROUND; - return (UNVIS_SYNBAD); - } -} - -/* - * strunvis - decode src into dst - * - * Number of chars decoded into dst is returned, -1 on error. - * Dst is null terminated. - */ - -int -strunvis(char *dst, const char *src) -{ - char c; - char *start = dst; - int state = 0; - - while ((c = *src++)) { - again: - switch (unvis(dst, c, &state, 0)) { - case UNVIS_VALID: - dst++; - break; - case UNVIS_VALIDPUSH: - dst++; - goto again; - case 0: - case UNVIS_NOCHAR: - break; - default: - *dst = '\0'; - return (-1); - } - } - if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) - dst++; - *dst = '\0'; - return (dst - start); -} - -ssize_t -strnunvis(char *dst, const char *src, size_t sz) -{ - char c, p; - char *start = dst, *end = dst + sz - 1; - int state = 0; - - if (sz > 0) - *end = '\0'; - while ((c = *src++)) { - again: - switch (unvis(&p, c, &state, 0)) { - case UNVIS_VALID: - if (dst < end) - *dst = p; - dst++; - break; - case UNVIS_VALIDPUSH: - if (dst < end) - *dst = p; - dst++; - goto again; - case 0: - case UNVIS_NOCHAR: - break; - default: - if (dst <= end) - *dst = '\0'; - return (-1); - } - } - if (unvis(&p, c, &state, UNVIS_END) == UNVIS_VALID) { - if (dst < end) - *dst = p; - dst++; - } - if (dst <= end) - *dst = '\0'; - return (dst - start); -} - diff --git a/var.c b/var.c @@ -1042,7 +1042,7 @@ setspec(struct tbl *vp) break; case V_RANDOM: vp->flag &= ~SPECIAL; - srand((unsigned int)intval(vp)); + srand_deterministic((unsigned int)intval(vp)); vp->flag |= SPECIAL; break; case V_SECONDS: diff --git a/vi.c b/vi.c @@ -14,6 +14,7 @@ #include <ctype.h> #include <stdlib.h> #include <string.h> +#include <sys/ttydefaults.h> #ifndef SMALL # include <term.h> # include <curses.h> diff --git a/vis.c b/vis.c @@ -1,241 +0,0 @@ -/* $OpenBSD: vis.c,v 1.25 2015/09/13 11:32:51 guenther Exp $ */ -/*- - * Copyright (c) 1989, 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 - * 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. 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. - */ - -#include <sys/types.h> -#include <errno.h> -#include <ctype.h> -#include <limits.h> -#include <string.h> -#include <stdlib.h> -#include <vis.h> - -#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define isvisible(c,flag) \ - (((c) == '\\' || (flag & VIS_ALL) == 0) && \ - (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \ - (((c) != '*' && (c) != '?' && (c) != '[' && (c) != '#') || \ - (flag & VIS_GLOB) == 0) && isgraph((u_char)(c))) || \ - ((flag & VIS_SP) == 0 && (c) == ' ') || \ - ((flag & VIS_TAB) == 0 && (c) == '\t') || \ - ((flag & VIS_NL) == 0 && (c) == '\n') || \ - ((flag & VIS_SAFE) && ((c) == '\b' || \ - (c) == '\007' || (c) == '\r' || \ - isgraph((u_char)(c)))))) - -/* - * vis - visually encode characters - */ -char * -vis(char *dst, int c, int flag, int nextc) -{ - if (isvisible(c, flag)) { - if ((c == '"' && (flag & VIS_DQ) != 0) || - (c == '\\' && (flag & VIS_NOSLASH) == 0)) - *dst++ = '\\'; - *dst++ = c; - *dst = '\0'; - return (dst); - } - - if (flag & VIS_CSTYLE) { - switch(c) { - case '\n': - *dst++ = '\\'; - *dst++ = 'n'; - goto done; - case '\r': - *dst++ = '\\'; - *dst++ = 'r'; - goto done; - case '\b': - *dst++ = '\\'; - *dst++ = 'b'; - goto done; - case '\a': - *dst++ = '\\'; - *dst++ = 'a'; - goto done; - case '\v': - *dst++ = '\\'; - *dst++ = 'v'; - goto done; - case '\t': - *dst++ = '\\'; - *dst++ = 't'; - goto done; - case '\f': - *dst++ = '\\'; - *dst++ = 'f'; - goto done; - case ' ': - *dst++ = '\\'; - *dst++ = 's'; - goto done; - case '\0': - *dst++ = '\\'; - *dst++ = '0'; - if (isoctal(nextc)) { - *dst++ = '0'; - *dst++ = '0'; - } - goto done; - } - } - if (((c & 0177) == ' ') || (flag & VIS_OCTAL) || - ((flag & VIS_GLOB) && (c == '*' || c == '?' || c == '[' || c == '#'))) { - *dst++ = '\\'; - *dst++ = ((u_char)c >> 6 & 07) + '0'; - *dst++ = ((u_char)c >> 3 & 07) + '0'; - *dst++ = ((u_char)c & 07) + '0'; - goto done; - } - if ((flag & VIS_NOSLASH) == 0) - *dst++ = '\\'; - if (c & 0200) { - c &= 0177; - *dst++ = 'M'; - } - if (iscntrl((u_char)c)) { - *dst++ = '^'; - if (c == 0177) - *dst++ = '?'; - else - *dst++ = c + '@'; - } else { - *dst++ = '-'; - *dst++ = c; - } -done: - *dst = '\0'; - return (dst); -} - -/* - * strvis, strnvis, strvisx - visually encode characters from src into dst - * - * Dst must be 4 times the size of src to account for possible - * expansion. The length of dst, not including the trailing NULL, - * is returned. - * - * Strnvis will write no more than siz-1 bytes (and will NULL terminate). - * The number of bytes needed to fully encode the string is returned. - * - * Strvisx encodes exactly len bytes from src into dst. - * This is useful for encoding a block of data. - */ -int -strvis(char *dst, const char *src, int flag) -{ - char c; - char *start; - - for (start = dst; (c = *src);) - dst = vis(dst, c, flag, *++src); - *dst = '\0'; - return (dst - start); -} - -int -strnvis(char *dst, const char *src, size_t siz, int flag) -{ - char *start, *end; - char tbuf[5]; - int c, i; - - i = 0; - for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { - if (isvisible(c, flag)) { - if ((c == '"' && (flag & VIS_DQ) != 0) || - (c == '\\' && (flag & VIS_NOSLASH) == 0)) { - /* need space for the extra '\\' */ - if (dst + 1 >= end) { - i = 2; - break; - } - *dst++ = '\\'; - } - i = 1; - *dst++ = c; - src++; - } else { - i = vis(tbuf, c, flag, *++src) - tbuf; - if (dst + i <= end) { - memcpy(dst, tbuf, i); - dst += i; - } else { - src--; - break; - } - } - } - if (siz > 0) - *dst = '\0'; - if (dst + i > end) { - /* adjust return value for truncation */ - while ((c = *src)) - dst += vis(tbuf, c, flag, *++src) - tbuf; - } - return (dst - start); -} - -int -stravis(char **outp, const char *src, int flag) -{ - char *buf; - int len, serrno; - - buf = reallocarray(NULL, 4, strlen(src) + 1); - if (buf == NULL) - return -1; - len = strvis(buf, src, flag); - serrno = errno; - *outp = realloc(buf, len + 1); - if (*outp == NULL) { - *outp = buf; - errno = serrno; - } - return (len); -} - -int -strvisx(char *dst, const char *src, size_t len, int flag) -{ - char c; - char *start; - - for (start = dst; len > 1; len--) { - c = *src; - dst = vis(dst, c, flag, *++src); - } - if (len) - dst = vis(dst, *src, flag, '\0'); - *dst = '\0'; - return (dst - start); -} diff --git a/vis.h b/vis.h @@ -1,88 +0,0 @@ -/* $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 millert Exp $ */ -/* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ - -/*- - * Copyright (c) 1990 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. 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. - * - * @(#)vis.h 5.9 (Berkeley) 4/3/91 - */ - -#ifndef _VIS_H_ -#define _VIS_H_ - -/* - * to select alternate encoding format - */ -#define VIS_OCTAL 0x01 /* use octal \ddd format */ -#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */ - -/* - * to alter set of characters encoded (default is to encode all - * non-graphic except space, tab, and newline). - */ -#define VIS_SP 0x04 /* also encode space */ -#define VIS_TAB 0x08 /* also encode tab */ -#define VIS_NL 0x10 /* also encode newline */ -#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) -#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ -#define VIS_DQ 0x200 /* backslash-escape double quotes */ -#define VIS_ALL 0x400 /* encode all characters */ - -/* - * other - */ -#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ -#define VIS_GLOB 0x100 /* encode glob(3) magics and '#' */ - -/* - * unvis return codes - */ -#define UNVIS_VALID 1 /* character valid */ -#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ -#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ -#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ -#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ - -/* - * unvis flags - */ -#define UNVIS_END 1 /* no more characters */ - -char *vis(char *, int, int, int); -int strvis(char *, const char *, int); -int stravis(char **, const char *, int); -int strnvis(char *, const char *, size_t, int) - __attribute__ ((__bounded__(__string__,1,3))); -int strvisx(char *, const char *, size_t, int) - __attribute__ ((__bounded__(__string__,1,3))); -int strunvis(char *, const char *); -int unvis(char *, char, int *, int); -ssize_t strnunvis(char *, const char *, size_t) - __attribute__ ((__bounded__(__string__,1,3))); - -#endif /* !_VIS_H_ */